on master help sign in
Merge pull request #505 from urbit/lf/deterministic-keyfiles-for-all
e1eacd9Fang
migrations/1_migration.js+3
@@ -119,6 +119,7 @@ module.exports = async function(deployer) {
119 await lsr.deposit(user1, offset);
119 await lsr.deposit(user1, offset);
120 await csr.deposit(user1, offset + 1);
120 await csr.deposit(user1, offset + 1);
121 }
121 }
122+ break;
122 case 'INVITES':
123 case 'INVITES':
123 await ecliptic.createGalaxy(0, own);
124 await ecliptic.createGalaxy(0, own);
124 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
125 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
@@ -130,6 +131,7 @@ module.exports = async function(deployer) {
130 await ecliptic.spawn(131328, own);
131 await ecliptic.spawn(131328, own);
131 await ecliptic.spawn(512, own);
132 await ecliptic.spawn(512, own);
132 await sending.setPoolSize(256, 65792, 1000);
133 await sending.setPoolSize(256, 65792, 1000);
134+ break;
133 case 'RESIDENTS':
135 case 'RESIDENTS':
134 await ecliptic.createGalaxy(0, own);
136 await ecliptic.createGalaxy(0, own);
135 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
137 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
@@ -141,6 +143,7 @@ module.exports = async function(deployer) {
141 await ecliptic.spawn(offset + 256, own);
143 await ecliptic.spawn(offset + 256, own);
142 await ecliptic.transferPoint(offset + 256, user1, false);
144 await ecliptic.transferPoint(offset + 256, user1, false);
143 }
145 }
146+ break;
144
147
145 default:
148 default:
146 return;
149 return;
src/lib/keys.js+30−1
@@ -6,6 +6,7 @@ import * as serial from '../nockjs/serial';
6import * as kg from 'urbit-key-generation';
6import * as kg from 'urbit-key-generation';
7
7
8import { eqAddr, addHexPrefix } from './wallet';
8import { eqAddr, addHexPrefix } from './wallet';
9+import { shas } from './networkCode';
9
10
10// the curve param for the network keys
11// the curve param for the network keys
11export const NETWORK_KEY_CURVE_PARAMETER = '42';
12export const NETWORK_KEY_CURVE_PARAMETER = '42';
@@ -142,6 +143,25 @@ const deriveNetworkSeedFromMnemonic = async (
142};
143};
143
144
144/**
145/**
146+ * @param {number} point
147+ * @param {string} authToken
148+ * @param {number} revision
149+ * @return {Maybe<string>}
150+ */
151+export const deriveNetworkSeedFromAuthToken = (point, authToken, revision) => {
152+ //NOTE revision is the point's on-chain revision number.
153+ // since deriveNetworkSeedFromMnemonic does this too, we decrement the
154+ // revision number by one before deriving from it.
155+ const salt = Buffer.from(`revision-${point}-${revision - 1}`);
156+ const networkSeed = shas(authToken, salt)
157+ .toString('hex')
158+ .slice(0, 32);
159+ return Just(networkSeed);
160+};
161+
162+/**
163+ * Derives from either a full Urbit Wallet, a current management mnemonic,
164+ * or an auth token, in that order of preference.
145 * @return {Promise<Maybe<string>>}
165 * @return {Promise<Maybe<string>>}
146 */
166 */
147export const attemptNetworkSeedDerivation = async ({
167export const attemptNetworkSeedDerivation = async ({
@@ -149,6 +169,8 @@ export const attemptNetworkSeedDerivation = async ({
149 wallet,
169 wallet,
150 authMnemonic,
170 authMnemonic,
151 details,
171 details,
172+ point,
173+ authToken,
152 revision,
174 revision,
153}) => {
175}) => {
154 if (Just.hasInstance(urbitWallet)) {
176 if (Just.hasInstance(urbitWallet)) {
@@ -156,12 +178,19 @@ export const attemptNetworkSeedDerivation = async ({
156 }
178 }
157
179
158 if (Just.hasInstance(wallet) && Just.hasInstance(authMnemonic)) {
180 if (Just.hasInstance(wallet) && Just.hasInstance(authMnemonic)) {
159− return await deriveNetworkSeedFromManagementMnemonic(
181+ const managementSeed = await deriveNetworkSeedFromManagementMnemonic(
160 wallet.value,
182 wallet.value,
161 authMnemonic.value,
183 authMnemonic.value,
162 details,
184 details,
163 revision
185 revision
164 );
186 );
187+ if (Just.hasInstance(managementSeed)) {
188+ return managementSeed;
189+ }
190+ }
191+
192+ if (Just.hasInstance(authToken)) {
193+ return deriveNetworkSeedFromAuthToken(point, authToken.value, revision);
165 }
194 }
166
195
167 return Nothing();
196 return Nothing();
src/lib/networkCode.js+5
@@ -23,6 +23,11 @@ export function shas(buf, salt) {
23}
23}
24
24
25function xor(a, b) {
25function xor(a, b) {
26+ if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
27+ console.log('a', a);
28+ console.log('b', b);
29+ throw new Error('only xor buffers!');
30+ }
26 const length = Math.max(a.byteLength, b.byteLength);
31 const length = Math.max(a.byteLength, b.byteLength);
27 const result = new Uint8Array(length);
32 const result = new Uint8Array(length);
28 for (let i = 0; i < length; i++) {
33 for (let i = 0; i < length; i++) {
src/lib/useInviter.js+1
@@ -204,6 +204,7 @@ const useInviter = () => {
204 return { invites: confirmedInvites };
204 return { invites: confirmedInvites };
205 },
205 },
206 [
206 [
207+ authToken,
207 contracts,
208 contracts,
208 gasPrice,
209 gasPrice,
209 networkType,
210 networkType,
src/lib/useKeyfileGenerator.js+4−1
@@ -20,7 +20,7 @@ import useCurrentPermissions from './useCurrentPermissions';
20import convertToInt from './convertToInt';
20import convertToInt from './convertToInt';
21
21
22export default function useKeyfileGenerator(manualNetworkSeed) {
22export default function useKeyfileGenerator(manualNetworkSeed) {
23− const { urbitWallet, wallet, authMnemonic } = useWallet();
23+ const { urbitWallet, wallet, authMnemonic, authToken } = useWallet();
24 const { pointCursor } = usePointCursor();
24 const { pointCursor } = usePointCursor();
25 const { getDetails } = usePointCache();
25 const { getDetails } = usePointCache();
26
26
@@ -63,6 +63,8 @@ export default function useKeyfileGenerator(manualNetworkSeed) {
63 wallet,
63 wallet,
64 authMnemonic,
64 authMnemonic,
65 details: _details,
65 details: _details,
66+ authToken,
67+ point: _point,
66 revision: networkRevision,
68 revision: networkRevision,
67 });
69 });
68
70
@@ -100,6 +102,7 @@ export default function useKeyfileGenerator(manualNetworkSeed) {
100 setCode,
102 setCode,
101 details,
103 details,
102 _point,
104 _point,
105+ authToken,
103 ]);
106 ]);
104
107
105 const filename = useMemo(() => {
108 const filename = useMemo(() => {
src/views/Invite/Cohort.js+1−1
@@ -205,7 +205,7 @@ function CohortMemberExpanded({ point, className, ...rest }) {
205 }
205 }
206 };
206 };
207 fetchWallet();
207 fetchWallet();
208− }, [codeVisible]);
208+ }, [authToken, codeVisible, contracts, details, point]);
209
209
210 useEffect(() => {
210 useEffect(() => {
211 setCodeVisible(false);
211 setCodeVisible(false);
src/views/IssueChild.js+1−1
@@ -117,7 +117,7 @@ export default function IssueChild() {
117 },
117 },
118 validateForm
118 validateForm
119 ),
119 ),
120− [validateForm]
120+ [_point, validateForm]
121 );
121 );
122
122
123 const onValues = useCallback(
123 const onValues = useCallback(
src/views/UrbitOS/NetworkingKeys.js+6−2
@@ -38,7 +38,7 @@ import FormError from 'form/FormError';
38import convertToInt from 'lib/convertToInt';
38import convertToInt from 'lib/convertToInt';
39
39
40function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
40function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
41− const { urbitWallet, wallet, authMnemonic } = useWallet();
41+ const { urbitWallet, wallet, authMnemonic, authToken } = useWallet();
42 const { pointCursor } = usePointCursor();
42 const { pointCursor } = usePointCursor();
43 const { syncDetails, syncRekeyDate, getDetails } = usePointCache();
43 const { syncDetails, syncRekeyDate, getDetails } = usePointCache();
44 const { contracts } = useNetwork();
44 const { contracts } = useNetwork();
@@ -71,6 +71,8 @@ function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
71 wallet,
71 wallet,
72 authMnemonic,
72 authMnemonic,
73 details: _details,
73 details: _details,
74+ point: _point,
75+ authToken,
74 revision: newNetworkRevision,
76 revision: newNetworkRevision,
75 });
77 });
76
78
@@ -87,10 +89,12 @@ function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
87 [
89 [
88 _details,
90 _details,
89 authMnemonic,
91 authMnemonic,
90− networkRevision,
91 setManualNetworkSeed,
92 setManualNetworkSeed,
93+ networkRevision,
92 urbitWallet,
94 urbitWallet,
93 wallet,
95 wallet,
96+ _point,
97+ authToken,
94 ]
98 ]
95 );
99 );
96
100