From c4e42949cf2824c5b778d7632adf72af2f2a57a3 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Tue, 28 Mar 2017 13:13:18 +0100
Subject: [PATCH] Simpler password strength estimation.

---
 .../api/crypto/PasswordStrengthEstimator.java |  6 ++---
 .../crypto/PasswordStrengthEstimatorImpl.java | 23 +++----------------
 .../PasswordStrengthEstimatorImplTest.java    |  3 ++-
 .../android/login/ChangePasswordActivity.java |  6 ++---
 .../briar/android/login/SetupActivity.java    |  6 ++---
 .../login/ChangePasswordActivityTest.java     |  6 ++---
 .../android/login/SetupActivityTest.java      |  6 ++---
 7 files changed, 20 insertions(+), 36 deletions(-)

diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PasswordStrengthEstimator.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PasswordStrengthEstimator.java
index 0fdb4a8ba5..f9cf35561d 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PasswordStrengthEstimator.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/PasswordStrengthEstimator.java
@@ -6,9 +6,9 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
 public interface PasswordStrengthEstimator {
 
 	float NONE = 0;
-	float WEAK = 0.4f;
-	float QUITE_WEAK = 0.6f;
-	float QUITE_STRONG = 0.8f;
+	float WEAK = 0.25f;
+	float QUITE_WEAK = 0.5f;
+	float QUITE_STRONG = 0.75f;
 	float STRONG = 1;
 
 	/**
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
index ad1a0148d8..67f745239b 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImpl.java
@@ -11,31 +11,14 @@ import javax.annotation.concurrent.Immutable;
 @NotNullByDefault
 class PasswordStrengthEstimatorImpl implements PasswordStrengthEstimator {
 
-	private static final int LOWER = 26;
-	private static final int UPPER = 26;
-	private static final int DIGIT = 10;
-	private static final int OTHER = 10;
-	private static final double STRONG = Math.log(Math.pow(LOWER + UPPER +
-			DIGIT + OTHER, 10));
+	// The minimum number of unique characters in a strong password
+	private static final int STRONG_UNIQUE_CHARS = 12;
 
 	@Override
 	public float estimateStrength(String password) {
 		HashSet<Character> unique = new HashSet<Character>();
 		int length = password.length();
 		for (int i = 0; i < length; i++) unique.add(password.charAt(i));
-		boolean lower = false, upper = false, digit = false, other = false;
-		for (char c : unique) {
-			if (Character.isLowerCase(c)) lower = true;
-			else if (Character.isUpperCase(c)) upper = true;
-			else if (Character.isDigit(c)) digit = true;
-			else other = true;
-		}
-		int alphabetSize = 0;
-		if (lower) alphabetSize += LOWER;
-		if (upper) alphabetSize += UPPER;
-		if (digit) alphabetSize += DIGIT;
-		if (other) alphabetSize += OTHER;
-		double score = Math.log(Math.pow(alphabetSize, unique.size()));
-		return Math.min(1, (float) (score / STRONG));
+		return Math.min(1, (float) unique.size() / STRONG_UNIQUE_CHARS);
 	}
 }
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImplTest.java
index 28f7e4bd21..8010ba4ad7 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/PasswordStrengthEstimatorImplTest.java
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
 import org.briarproject.bramble.test.BrambleTestCase;
 import org.junit.Test;
 
+import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.NONE;
 import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
 import static org.junit.Assert.assertTrue;
 
@@ -12,7 +13,7 @@ public class PasswordStrengthEstimatorImplTest extends BrambleTestCase {
 	@Test
 	public void testWeakPasswords() {
 		PasswordStrengthEstimator e = new PasswordStrengthEstimatorImpl();
-		assertTrue(e.estimateStrength("") < QUITE_STRONG);
+		assertTrue(e.estimateStrength("") == NONE);
 		assertTrue(e.estimateStrength("password") < QUITE_STRONG);
 		assertTrue(e.estimateStrength("letmein") < QUITE_STRONG);
 		assertTrue(e.estimateStrength("123456") < QUITE_STRONG);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java
index 6bd309d5c4..cea17a2ebb 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/ChangePasswordActivity.java
@@ -25,7 +25,7 @@ import javax.inject.Inject;
 
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
-import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
+import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
 
 public class ChangePasswordActivity extends BaseActivity
 		implements OnClickListener, OnEditorActionListener {
@@ -109,13 +109,13 @@ public class ChangePasswordActivity extends BaseActivity
 		strengthMeter.setStrength(strength);
 		UiUtils.setError(newPasswordEntryWrapper,
 				getString(R.string.password_too_weak),
-				firstPassword.length() > 0 && strength < WEAK);
+				firstPassword.length() > 0 && strength < QUITE_WEAK);
 		UiUtils.setError(newPasswordConfirmationWrapper,
 				getString(R.string.passwords_do_not_match),
 				secondPassword.length() > 0 && !passwordsMatch);
 		changePasswordButton.setEnabled(
 				!currentPassword.getText().toString().isEmpty() &&
-						passwordsMatch && strength >= WEAK);
+						passwordsMatch && strength >= QUITE_WEAK);
 	}
 
 	@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupActivity.java
index decf81f76b..767a9eb558 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupActivity.java
@@ -28,7 +28,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
-import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
+import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
 
 public class SetupActivity extends BaseActivity implements OnClickListener,
@@ -115,13 +115,13 @@ public class SetupActivity extends BaseActivity implements OnClickListener,
 				nicknameLength > MAX_AUTHOR_NAME_LENGTH);
 		UiUtils.setError(passwordEntryWrapper,
 				getString(R.string.password_too_weak),
-				firstPassword.length() > 0 && strength < WEAK);
+				firstPassword.length() > 0 && strength < QUITE_WEAK);
 		UiUtils.setError(passwordConfirmationWrapper,
 				getString(R.string.passwords_do_not_match),
 				secondPassword.length() > 0 && !passwordsMatch);
 		createAccountButton.setEnabled(nicknameLength > 0
 				&& nicknameLength <= MAX_AUTHOR_NAME_LENGTH
-				&& passwordsMatch && strength >= WEAK);
+				&& passwordsMatch && strength >= QUITE_WEAK);
 	}
 
 	@Override
diff --git a/briar-android/src/test/java/org/briarproject/briar/android/login/ChangePasswordActivityTest.java b/briar-android/src/test/java/org/briarproject/briar/android/login/ChangePasswordActivityTest.java
index d163c8c509..5721921889 100644
--- a/briar-android/src/test/java/org/briarproject/briar/android/login/ChangePasswordActivityTest.java
+++ b/briar-android/src/test/java/org/briarproject/briar/android/login/ChangePasswordActivityTest.java
@@ -193,7 +193,7 @@ public class ChangePasswordActivityTest {
 		// Mock answers for UI testing only
 		when(mockedController.estimatePasswordStrength("strong")).thenReturn(
 				STRONG);
-		when(mockedController.estimatePasswordStrength("qstring")).thenReturn(
+		when(mockedController.estimatePasswordStrength("qstrong")).thenReturn(
 				QUITE_STRONG);
 		when(mockedController.estimatePasswordStrength("qweak")).thenReturn(
 				QUITE_WEAK);
@@ -205,9 +205,9 @@ public class ChangePasswordActivityTest {
 		testStrengthMeter("strong", STRONG, StrengthMeter.GREEN);
 		Mockito.verify(mockedController, Mockito.times(1))
 				.estimatePasswordStrength(eq("strong"));
-		testStrengthMeter("qstring", QUITE_STRONG, StrengthMeter.LIME);
+		testStrengthMeter("qstrong", QUITE_STRONG, StrengthMeter.LIME);
 		Mockito.verify(mockedController, Mockito.times(1))
-				.estimatePasswordStrength(eq("qstring"));
+				.estimatePasswordStrength(eq("qstrong"));
 		testStrengthMeter("qweak", QUITE_WEAK, StrengthMeter.YELLOW);
 		Mockito.verify(mockedController, Mockito.times(1))
 				.estimatePasswordStrength(eq("qweak"));
diff --git a/briar-android/src/test/java/org/briarproject/briar/android/login/SetupActivityTest.java b/briar-android/src/test/java/org/briarproject/briar/android/login/SetupActivityTest.java
index 86472493c7..2d500c998b 100644
--- a/briar-android/src/test/java/org/briarproject/briar/android/login/SetupActivityTest.java
+++ b/briar-android/src/test/java/org/briarproject/briar/android/login/SetupActivityTest.java
@@ -196,7 +196,7 @@ public class SetupActivityTest {
 		// Mock answers for UI testing only
 		when(mockedController.estimatePasswordStrength("strong")).thenReturn(
 				STRONG);
-		when(mockedController.estimatePasswordStrength("qstring")).thenReturn(
+		when(mockedController.estimatePasswordStrength("qstrong")).thenReturn(
 				QUITE_STRONG);
 		when(mockedController.estimatePasswordStrength("qweak")).thenReturn(
 				QUITE_WEAK);
@@ -208,9 +208,9 @@ public class SetupActivityTest {
 		testStrengthMeter("strong", STRONG, StrengthMeter.GREEN);
 		Mockito.verify(mockedController, Mockito.times(1))
 				.estimatePasswordStrength(eq("strong"));
-		testStrengthMeter("qstring", QUITE_STRONG, StrengthMeter.LIME);
+		testStrengthMeter("qstrong", QUITE_STRONG, StrengthMeter.LIME);
 		Mockito.verify(mockedController, Mockito.times(1))
-				.estimatePasswordStrength(eq("qstring"));
+				.estimatePasswordStrength(eq("qstrong"));
 		testStrengthMeter("qweak", QUITE_WEAK, StrengthMeter.YELLOW);
 		Mockito.verify(mockedController, Mockito.times(1))
 				.estimatePasswordStrength(eq("qweak"));
-- 
GitLab