diff options
author | Kenny Root <kenny@the-b.org> | 2009-06-07 08:22:21 +0000 |
---|---|---|
committer | Kenny Root <kenny@the-b.org> | 2009-06-07 08:22:21 +0000 |
commit | d1e00c2f279169737fb15dd10287317d06d64ea5 (patch) | |
tree | 013450307066e8bde45083e0f286faa354a05f9f /src/org | |
parent | 564bde5c42170592fdeed845e19fd102ae2865aa (diff) | |
download | connectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.tar.gz connectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.tar.bz2 connectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.zip |
Add von Neumann whitening to entropy gathering
git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@273 df292f66-193f-0410-a5fc-6d59da041ff2
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/connectbot/GeneratePubkeyActivity.java | 18 | ||||
-rw-r--r-- | src/org/connectbot/util/EntropyView.java | 51 |
2 files changed, 56 insertions, 13 deletions
diff --git a/src/org/connectbot/GeneratePubkeyActivity.java b/src/org/connectbot/GeneratePubkeyActivity.java index 17a0bea..cb565f4 100644 --- a/src/org/connectbot/GeneratePubkeyActivity.java +++ b/src/org/connectbot/GeneratePubkeyActivity.java @@ -213,6 +213,12 @@ public class GeneratePubkeyActivity extends Activity implements OnEntropyGathere this.entropy = entropy.clone(); + int numSetBits = 0; + for (int i = 0; i < 20; i++) + numSetBits += measureNumberOfSetBits(this.entropy[i]); + + Log.d(TAG, "Entropy distribution=" + (int)(100.0 * numSetBits / 160.0) + "%"); + Log.d(TAG, "entropy gathered; attemping to generate key..."); startKeyGen(); } @@ -294,4 +300,16 @@ public class GeneratePubkeyActivity extends Activity implements OnEntropyGathere checkEntries(); } }; + + private int measureNumberOfSetBits(byte b) { + int numSetBits = 0; + + for (int i = 0; i < 8; i++) { + if ((b & 1) == 1) + numSetBits++; + b >>= 1; + } + + return numSetBits; + } } diff --git a/src/org/connectbot/util/EntropyView.java b/src/org/connectbot/util/EntropyView.java index 55bebce..22a2745 100644 --- a/src/org/connectbot/util/EntropyView.java +++ b/src/org/connectbot/util/EntropyView.java @@ -32,6 +32,9 @@ import android.view.MotionEvent; import android.view.View; public class EntropyView extends View { + private static final int SHA1_MAX_BYTES = 20; + private static final int MILLIS_BETWEEN_INPUTS = 50; + private Paint mPaint; private FontMetrics mFontMetrics; private boolean mFlipFlop; @@ -39,7 +42,8 @@ public class EntropyView extends View { private Vector<OnEntropyGatheredListener> listeners; private byte[] mEntropy; - private int mEntropyIdx; + private int mEntropyByteIndex; + private int mEntropyBitIndex; private int splitText = 0; @@ -66,8 +70,9 @@ public class EntropyView extends View { mPaint.setColor(Color.WHITE); mFontMetrics = mPaint.getFontMetrics(); - mEntropy = new byte[20]; - mEntropyIdx = 0; + mEntropy = new byte[SHA1_MAX_BYTES]; + mEntropyByteIndex = 0; + mEntropyBitIndex = 0; listeners = new Vector<OnEntropyGatheredListener>(); } @@ -83,7 +88,7 @@ public class EntropyView extends View { @Override public void onDraw(Canvas c) { String prompt = String.format(getResources().getString(R.string.pubkey_touch_prompt), - (int)(100.0 * (mEntropyIdx / 20.0))); + (int)(100.0 * (mEntropyByteIndex / 20.0)) + (int)(5.0 * (mEntropyBitIndex / 8.0))); if (splitText > 0 || mPaint.measureText(prompt) > (getWidth() * 0.8)) { if (splitText == 0) @@ -107,31 +112,51 @@ public class EntropyView extends View { @Override public boolean onTouchEvent(MotionEvent event) { - if (mEntropyIdx >= 20 + if (mEntropyByteIndex >= SHA1_MAX_BYTES || lastX == event.getX() || lastY == event.getY()) return true; // Only get entropy every 200 milliseconds to ensure the user has moved around. long now = System.currentTimeMillis(); - if ((now - mLastTime) < 200) + if ((now - mLastTime) < MILLIS_BETWEEN_INPUTS) return true; else mLastTime = now; + byte input; + + lastX = event.getX(); + lastY = event.getY(); + // Get the lowest 4 bits of each X, Y input and concat to the entropy-gathering // string. if (mFlipFlop) - mEntropy[mEntropyIdx++] += (byte)((((int)event.getX() & 0x0F) << 4) | ((int)event.getY() & 0x0F)); + input = (byte)((((int)lastX & 0x0F) << 4) | ((int)lastY & 0x0F)); else - mEntropy[mEntropyIdx++] += (byte)((((int)event.getY() & 0x0F) << 4) | ((int)event.getX() & 0x0F)); - + input = (byte)((((int)lastY & 0x0F) << 4) | ((int)lastX & 0x0F)); mFlipFlop = !mFlipFlop; - lastX = event.getX(); - lastY = event.getY(); - // SHA1PRNG only keeps 20 bytes (160 bits) of entropy. - if (mEntropyIdx >= 20) { + for (int i = 0; i < 4 && mEntropyByteIndex < SHA1_MAX_BYTES; i++) { + if ((input & 0x3) == 0x1) { + mEntropy[mEntropyByteIndex] <<= 1; + mEntropy[mEntropyByteIndex] |= 1; + mEntropyBitIndex++; + input >>= 2; + } else if ((input & 0x3) == 0x2) { + mEntropy[mEntropyByteIndex] <<= 1; + mEntropyBitIndex++; + input >>= 2; + } + + if (mEntropyBitIndex >= 8) { + mEntropyBitIndex = 0; + mEntropyByteIndex++; + } + } + + // SHA1PRNG only keeps 160 bits of entropy. + if (mEntropyByteIndex >= SHA1_MAX_BYTES) { for (OnEntropyGatheredListener listener: listeners) { listener.onEntropyGathered(mEntropy); } |