on master help sign in
Merge pull request #505 from urbit/lf/deterministic-keyfiles-for-all

keyfiles: make all keyfiles deterministic

commite1eacd9d7987064ebac0ca26fd49d0ce6bc982d1 authorFang <git@fang.io> dateFri 24 Jul 2020, 23:42 (6 years ago) parentd93d23ecc9183b
8 files changed+51−6
migrations/1_migration.js+3 src/lib/keys.js+30−1 src/lib/networkCode.js+5 src/lib/useInviter.js+1 src/lib/useKeyfileGenerator.js+4−1 src/views/Invite/Cohort.js+1−1 src/views/IssueChild.js+1−1 src/views/UrbitOS/NetworkingKeys.js+6−2
migrations/1_migration.js+3
@@ -119,6 +119,7 @@ module.exports = async function(deployer) {
119119 await lsr.deposit(user1, offset);
120120 await csr.deposit(user1, offset + 1);
121121 }
122+ break;
122123 case 'INVITES':
123124 await ecliptic.createGalaxy(0, own);
124125 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
@@ -130,6 +131,7 @@ module.exports = async function(deployer) {
130131 await ecliptic.spawn(131328, own);
131132 await ecliptic.spawn(512, own);
132133 await sending.setPoolSize(256, 65792, 1000);
134+ break;
133135 case 'RESIDENTS':
134136 await ecliptic.createGalaxy(0, own);
135137 await ecliptic.configureKeys(0, '0x123', '0x456', 1, false);
@@ -141,6 +143,7 @@ module.exports = async function(deployer) {
141143 await ecliptic.spawn(offset + 256, own);
142144 await ecliptic.transferPoint(offset + 256, user1, false);
143145 }
146+ break;
144147
145148 default:
146149 return;
src/lib/keys.js+30−1
@@ -6,6 +6,7 @@ import * as serial from '../nockjs/serial';
66import * as kg from 'urbit-key-generation';
77
88import { eqAddr, addHexPrefix } from './wallet';
9+import { shas } from './networkCode';
910
1011// the curve param for the network keys
1112export const NETWORK_KEY_CURVE_PARAMETER = '42';
@@ -142,6 +143,25 @@ const deriveNetworkSeedFromMnemonic = async (
142143};
143144
144145/**
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.
145165 * @return {Promise<Maybe<string>>}
146166 */
147167export const attemptNetworkSeedDerivation = async ({
@@ -149,6 +169,8 @@ export const attemptNetworkSeedDerivation = async ({
149169 wallet,
150170 authMnemonic,
151171 details,
172+ point,
173+ authToken,
152174 revision,
153175}) => {
154176 if (Just.hasInstance(urbitWallet)) {
@@ -156,12 +178,19 @@ export const attemptNetworkSeedDerivation = async ({
156178 }
157179
158180 if (Just.hasInstance(wallet) && Just.hasInstance(authMnemonic)) {
159− return await deriveNetworkSeedFromManagementMnemonic(
181+ const managementSeed = await deriveNetworkSeedFromManagementMnemonic(
160182 wallet.value,
161183 authMnemonic.value,
162184 details,
163185 revision
164186 );
187+ if (Just.hasInstance(managementSeed)) {
188+ return managementSeed;
189+ }
190+ }
191+
192+ if (Just.hasInstance(authToken)) {
193+ return deriveNetworkSeedFromAuthToken(point, authToken.value, revision);
165194 }
166195
167196 return Nothing();
src/lib/networkCode.js+5
@@ -23,6 +23,11 @@ export function shas(buf, salt) {
2323}
2424
2525function 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+ }
2631 const length = Math.max(a.byteLength, b.byteLength);
2732 const result = new Uint8Array(length);
2833 for (let i = 0; i < length; i++) {
src/lib/useInviter.js+1
@@ -204,6 +204,7 @@ const useInviter = () => {
204204 return { invites: confirmedInvites };
205205 },
206206 [
207+ authToken,
207208 contracts,
208209 gasPrice,
209210 networkType,
src/lib/useKeyfileGenerator.js+4−1
@@ -20,7 +20,7 @@ import useCurrentPermissions from './useCurrentPermissions';
2020import convertToInt from './convertToInt';
2121
2222export default function useKeyfileGenerator(manualNetworkSeed) {
23− const { urbitWallet, wallet, authMnemonic } = useWallet();
23+ const { urbitWallet, wallet, authMnemonic, authToken } = useWallet();
2424 const { pointCursor } = usePointCursor();
2525 const { getDetails } = usePointCache();
2626
@@ -63,6 +63,8 @@ export default function useKeyfileGenerator(manualNetworkSeed) {
6363 wallet,
6464 authMnemonic,
6565 details: _details,
66+ authToken,
67+ point: _point,
6668 revision: networkRevision,
6769 });
6870
@@ -100,6 +102,7 @@ export default function useKeyfileGenerator(manualNetworkSeed) {
100102 setCode,
101103 details,
102104 _point,
105+ authToken,
103106 ]);
104107
105108 const filename = useMemo(() => {
src/views/Invite/Cohort.js+1−1
@@ -205,7 +205,7 @@ function CohortMemberExpanded({ point, className, ...rest }) {
205205 }
206206 };
207207 fetchWallet();
208− }, [codeVisible]);
208+ }, [authToken, codeVisible, contracts, details, point]);
209209
210210 useEffect(() => {
211211 setCodeVisible(false);
src/views/IssueChild.js+1−1
@@ -117,7 +117,7 @@ export default function IssueChild() {
117117 },
118118 validateForm
119119 ),
120− [validateForm]
120+ [_point, validateForm]
121121 );
122122
123123 const onValues = useCallback(
src/views/UrbitOS/NetworkingKeys.js+6−2
@@ -38,7 +38,7 @@ import FormError from 'form/FormError';
3838import convertToInt from 'lib/convertToInt';
3939
4040function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
41− const { urbitWallet, wallet, authMnemonic } = useWallet();
41+ const { urbitWallet, wallet, authMnemonic, authToken } = useWallet();
4242 const { pointCursor } = usePointCursor();
4343 const { syncDetails, syncRekeyDate, getDetails } = usePointCache();
4444 const { contracts } = useNetwork();
@@ -71,6 +71,8 @@ function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
7171 wallet,
7272 authMnemonic,
7373 details: _details,
74+ point: _point,
75+ authToken,
7476 revision: newNetworkRevision,
7577 });
7678
@@ -87,10 +89,12 @@ function useSetKeys(manualNetworkSeed, setManualNetworkSeed) {
8789 [
8890 _details,
8991 authMnemonic,
90− networkRevision,
9192 setManualNetworkSeed,
93+ networkRevision,
9294 urbitWallet,
9395 wallet,
96+ _point,
97+ authToken,
9498 ]
9599 );
96100