diff --git a/lib/shared/state-sync/current-user-state-sync-spec.js b/lib/shared/state-sync/current-user-state-sync-spec.js
--- a/lib/shared/state-sync/current-user-state-sync-spec.js
+++ b/lib/shared/state-sync/current-user-state-sync-spec.js
@@ -1,11 +1,15 @@
 // @flow
 
+import { createSelector } from 'reselect';
+
 import type { StateSyncSpec } from './state-sync-spec.js';
+import type { AppState } from '../../types/redux-types';
 import {
   type CurrentUserInfo,
   currentUserInfoValidator,
 } from '../../types/user-types.js';
 import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js';
+import { hash } from '../../utils/objects.js';
 import { ashoatKeyserverID } from '../../utils/validation-utils.js';
 
 export const currentUserStateSyncSpec: StateSyncSpec<
@@ -24,4 +28,13 @@
   findStoreInconsistencies() {
     return undefined;
   },
+  selector: createSelector(
+    (state: AppState) => state.currentUserInfo,
+    currentUserInfo => ({
+      ...currentUserStateSyncSpec,
+      getInfoHash: () => hash(currentUserInfo),
+      getAllInfosHash: () => hash(currentUserInfo),
+      getIDs: () => [],
+    }),
+  ),
 });
diff --git a/lib/shared/state-sync/entries-state-sync-spec.js b/lib/shared/state-sync/entries-state-sync-spec.js
--- a/lib/shared/state-sync/entries-state-sync-spec.js
+++ b/lib/shared/state-sync/entries-state-sync-spec.js
@@ -1,6 +1,7 @@
 // @flow
 
 import _isEqual from 'lodash/fp/isEqual.js';
+import { createSelector } from 'reselect';
 import t from 'tcomb';
 
 import type { StateSyncSpec } from './state-sync-spec.js';
@@ -10,6 +11,7 @@
   rawEntryInfoValidator,
   type RawEntryInfo,
 } from '../../types/entry-types.js';
+import type { AppState } from '../../types/redux-types.js';
 import {
   reportTypes,
   type ClientEntryInconsistencyReportCreationRequest,
@@ -18,7 +20,7 @@
 import { actionLogger } from '../../utils/action-logger.js';
 import { getConfig } from '../../utils/config.js';
 import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js';
-import { values } from '../../utils/objects.js';
+import { values, combineUnorderedHashes, hash } from '../../utils/objects.js';
 import { generateReportID } from '../../utils/report-utils.js';
 import { sanitizeActionSecrets } from '../../utils/sanitization.js';
 import { ashoatKeyserverID, tID } from '../../utils/validation-utils.js';
@@ -87,6 +89,37 @@
       },
     ];
   },
+  selector: createSelector(
+    (state: AppState) => state.entryStore.entryInfos,
+    entryInfos => ({
+      ...entriesStateSyncSpec,
+      getInfoHash: id => hash(entryInfos[`${ashoatKeyserverID}|${id}`]),
+      getAllInfosHash: calendarQuery =>
+        getEntryInfosHash(entryInfos, calendarQuery),
+      getIDs: calendarQuery => getEntryIDs(entryInfos, calendarQuery),
+    }),
+  ),
 });
 
 const emptyArray = [];
+
+function getEntryInfosHash(
+  entryInfos: RawEntryInfos,
+  calendarQuery: CalendarQuery,
+) {
+  const filteredEntryInfos = filterRawEntryInfosByCalendarQuery(
+    serverEntryInfosObject(values(entryInfos)),
+    calendarQuery,
+  );
+
+  return combineUnorderedHashes(Object.values(filteredEntryInfos).map(hash));
+}
+
+function getEntryIDs(entryInfos: RawEntryInfos, calendarQuery: CalendarQuery) {
+  const filteredEntryInfos = filterRawEntryInfosByCalendarQuery(
+    serverEntryInfosObject(values(entryInfos)),
+    calendarQuery,
+  );
+
+  return Object.keys(filteredEntryInfos).map(id => id.split('|')[1]);
+}
diff --git a/lib/shared/state-sync/state-sync-spec.js b/lib/shared/state-sync/state-sync-spec.js
--- a/lib/shared/state-sync/state-sync-spec.js
+++ b/lib/shared/state-sync/state-sync-spec.js
@@ -1,6 +1,7 @@
 // @flow
 
 import type { CalendarQuery } from '../../types/entry-types.js';
+import type { AppState } from '../../types/redux-types.js';
 import type { ProcessServerRequestAction } from '../../types/request-types.js';
 
 export type StateSyncSpec<Infos, Info, Inconsistencies> = {
@@ -20,4 +21,19 @@
     beforeStateCheck: Infos,
     afterStateCheck: Infos,
   ) => Inconsistencies,
+  +selector: (
+    state: AppState,
+  ) => BoundStateSyncSpec<Infos, Info, Inconsistencies>,
+};
+
+// All ids specified here (getInfoHash and getIDs) are server ids.
+// E.g. in the case of threadStore or entryStore the keyserver prefix
+// needs to be handled additionaly
+export type BoundStateSyncSpec<Infos, Info, Inconsistencies> = {
+  // If these function depend on background hashing that is still not complete
+  // they should return  null, to indicate that the hashes aren't available yet
+  +getInfoHash: (id: string) => ?number,
+  +getAllInfosHash: (query: CalendarQuery) => ?number,
+  +getIDs: (query: CalendarQuery) => ?Array<string>,
+  ...StateSyncSpec<Infos, Info, Inconsistencies>,
 };
diff --git a/lib/shared/state-sync/threads-state-sync-spec.js b/lib/shared/state-sync/threads-state-sync-spec.js
--- a/lib/shared/state-sync/threads-state-sync-spec.js
+++ b/lib/shared/state-sync/threads-state-sync-spec.js
@@ -1,9 +1,11 @@
 // @flow
 
 import _isEqual from 'lodash/fp/isEqual.js';
+import { createSelector } from 'reselect';
 import t from 'tcomb';
 
 import type { StateSyncSpec } from './state-sync-spec.js';
+import type { AppState } from '../../types/redux-types.js';
 import {
   reportTypes,
   type ClientThreadInconsistencyReportCreationRequest,
@@ -17,6 +19,7 @@
 import { actionLogger } from '../../utils/action-logger.js';
 import { getConfig } from '../../utils/config.js';
 import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js';
+import { combineUnorderedHashes, values } from '../../utils/objects.js';
 import { generateReportID } from '../../utils/report-utils.js';
 import { sanitizeActionSecrets } from '../../utils/sanitization.js';
 import { ashoatKeyserverID, tID } from '../../utils/validation-utils.js';
@@ -60,6 +63,21 @@
       },
     ];
   },
+  selector: createSelector(
+    (state: AppState) => state.integrityStore.threadHashes,
+    (state: AppState) =>
+      state.integrityStore.threadHashingStatus === 'completed',
+    (threadHashes, threadHashingComplete) => ({
+      ...threadsStateSyncSpec,
+      getInfoHash: id => threadHashes[`${ashoatKeyserverID}|${id}`],
+      getAllInfosHash: threadHashingComplete
+        ? () => combineUnorderedHashes(values(threadHashes))
+        : () => null,
+      getIDs: threadHashingComplete
+        ? () => Object.keys(threadHashes).map(id => id.split('|')[1])
+        : () => null,
+    }),
+  ),
 });
 
 const emptyArray = [];
diff --git a/lib/shared/state-sync/users-state-sync-spec.js b/lib/shared/state-sync/users-state-sync-spec.js
--- a/lib/shared/state-sync/users-state-sync-spec.js
+++ b/lib/shared/state-sync/users-state-sync-spec.js
@@ -1,8 +1,10 @@
 // @flow
 
 import _isEqual from 'lodash/fp/isEqual.js';
+import { createSelector } from 'reselect';
 
 import type { StateSyncSpec } from './state-sync-spec.js';
+import type { AppState } from '../../types/redux-types';
 import {
   reportTypes,
   type UserInconsistencyReportCreationRequest,
@@ -16,6 +18,7 @@
 import { actionLogger } from '../../utils/action-logger.js';
 import { getConfig } from '../../utils/config.js';
 import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js';
+import { combineUnorderedHashes, hash } from '../../utils/objects.js';
 import { generateReportID } from '../../utils/report-utils.js';
 import { sanitizeActionSecrets } from '../../utils/sanitization.js';
 import { ashoatKeyserverID } from '../../utils/validation-utils.js';
@@ -62,6 +65,16 @@
       },
     ];
   },
+  selector: createSelector(
+    (state: AppState) => state.userStore.userInfos,
+    userInfos => ({
+      ...usersStateSyncSpec,
+      getInfoHash: id => hash(userInfos[id]),
+      getAllInfosHash: () =>
+        combineUnorderedHashes(Object.values(userInfos).map(hash)),
+      getIDs: () => Object.keys(userInfos),
+    }),
+  ),
 });
 
 const emptyArray = [];