diff --git a/main.js b/main.js
index 0b4f7f688..68a04b572 100644
--- a/main.js
+++ b/main.js
@@ -54,7 +54,7 @@ const config = require('./app/config');
 // Very important to put before the single instance check, since it is based on the
 //   userData directory.
 const userConfig = require('./app/user_config');
-const passwordUtil = require('./app/password_util');
+const passwordUtil = require('./ts/util/passwordUtils');
 
 const importMode =
   process.argv.some(arg => arg === '--import') || config.get('import');
diff --git a/password_preload.js b/password_preload.js
index bd18b92db..d5c29af89 100644
--- a/password_preload.js
+++ b/password_preload.js
@@ -40,7 +40,7 @@ window.CONSTANTS = {
   MAX_USERNAME_LENGTH: 20,
 };
 
-window.passwordUtil = require('./app/password_util');
+window.passwordUtil = require('./ts/util/passwordUtils');
 window.Signal.Logs = require('./js/modules/logs');
 
 window.resetDatabase = () => {
diff --git a/preload.js b/preload.js
index 457de7c11..bf4471ec0 100644
--- a/preload.js
+++ b/preload.js
@@ -164,7 +164,7 @@ window.setPassword = (passPhrase, oldPhrase) =>
     ipc.send('set-password', passPhrase, oldPhrase);
   });
 
-window.passwordUtil = require('./app/password_util');
+window.passwordUtil = require('./ts/util/passwordUtils');
 window.libsession = require('./ts/session');
 
 // We never do these in our code, so we'll prevent it everywhere
diff --git a/test/app/password_util_test.js b/test/app/password_util_test.js
index 700b99c74..7037ec32e 100644
--- a/test/app/password_util_test.js
+++ b/test/app/password_util_test.js
@@ -1,6 +1,6 @@
 const { assert } = require('chai');
 
-const passwordUtil = require('../../app/password_util');
+const passwordUtil = require('../../ts/util/passwordUtils');
 
 describe('Password Util', () => {
   describe('hash generation', () => {
diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx
index 2cf3c6c5a..a00f56ab8 100644
--- a/ts/components/session/SessionPasswordModal.tsx
+++ b/ts/components/session/SessionPasswordModal.tsx
@@ -2,7 +2,7 @@ import React from 'react';
 
 import { SessionModal } from './SessionModal';
 import { SessionButton, SessionButtonColor } from './SessionButton';
-
+import { PasswordUtil } from '../../util/';
 export enum PasswordAction {
   Set = 'set',
   Change = 'change',
@@ -117,7 +117,7 @@ export class SessionPasswordModal extends React.Component<Props, State> {
   public async validatePasswordHash(password: string | null) {
     // Check if the password matches the hash we have stored
     const hash = await window.Signal.Data.getPasswordHash();
-    if (hash && !window.passwordUtil.matchesHash(password, hash)) {
+    if (hash && !PasswordUtil.matchesHash(password, hash)) {
       return false;
     }
 
@@ -153,7 +153,7 @@ export class SessionPasswordModal extends React.Component<Props, State> {
     const enteredPasswordConfirm = (currentPasswordConfirmEntered || '').trim();
 
     // if user did not fill the first password field, we can't do anything
-    const errorFirstInput = window.passwordUtil.validatePassword(
+    const errorFirstInput = PasswordUtil.validatePassword(
       enteredPassword,
       window.i18n
     );
@@ -166,7 +166,7 @@ export class SessionPasswordModal extends React.Component<Props, State> {
 
     // if action is Set or Change, we need a valid ConfirmPassword
     if (action === Set || action === Change) {
-      const errorSecondInput = window.passwordUtil.validatePassword(
+      const errorSecondInput = PasswordUtil.validatePassword(
         enteredPasswordConfirm,
         window.i18n
       );
diff --git a/ts/util/index.ts b/ts/util/index.ts
index c5428412b..699b5fcb8 100644
--- a/ts/util/index.ts
+++ b/ts/util/index.ts
@@ -5,6 +5,7 @@ import { missingCaseError } from './missingCaseError';
 import { migrateColor } from './migrateColor';
 import { makeLookup } from './makeLookup';
 import * as UserUtil from './user';
+import * as PasswordUtil from './passwordUtils';
 
 export * from './blockedNumberController';
 
@@ -16,4 +17,5 @@ export {
   migrateColor,
   missingCaseError,
   UserUtil,
+  PasswordUtil,
 };
diff --git a/app/password_util.js b/ts/util/passwordUtils.ts
similarity index 73%
rename from app/password_util.js
rename to ts/util/passwordUtils.ts
index 75fb0fb25..ea2ca0d24 100644
--- a/app/password_util.js
+++ b/ts/util/passwordUtils.ts
@@ -1,4 +1,5 @@
-const crypto = require('crypto');
+import * as crypto from 'crypto';
+import { LocalizerType } from '../types/Util';
 
 const ERRORS = {
   TYPE: 'Password must be a string',
@@ -6,17 +7,17 @@ const ERRORS = {
   CHARACTER: 'Password must only contain letters, numbers and symbols',
 };
 
-const sha512 = text => {
+const sha512 = (text: string) => {
   const hash = crypto.createHash('sha512');
   hash.update(text.trim());
   return hash.digest('hex');
 };
 
-const generateHash = phrase => phrase && sha512(phrase.trim());
-const matchesHash = (phrase, hash) =>
+export const generateHash = (phrase: string) => phrase && sha512(phrase.trim());
+export const matchesHash = (phrase: string | null, hash: string) =>
   phrase && sha512(phrase.trim()) === hash.trim();
 
-const validatePassword = (phrase, i18n) => {
+export const validatePassword = (phrase: string, i18n: LocalizerType) => {
   if (typeof phrase !== 'string') {
     return i18n ? i18n('passwordTypeError') : ERRORS.TYPE;
   }
@@ -38,9 +39,3 @@ const validatePassword = (phrase, i18n) => {
 
   return null;
 };
-
-module.exports = {
-  generateHash,
-  matchesHash,
-  validatePassword,
-};