From 031b7ebb0adad19ae2db914c79de162d2e3de445 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 31 Jul 2014 15:35:04 +0200 Subject: [PATCH] add Unicode compressions marker --- .../android/secretshare/ApplicationTest.java | 7 +- .../android/secretshare/GenerateFragment.java | 29 ++---- .../android/secretshare/Renderer.java | 93 ++++++++++++++----- 3 files changed, 82 insertions(+), 47 deletions(-) diff --git a/app/src/androidTest/java/org/surfsite/android/secretshare/ApplicationTest.java b/app/src/androidTest/java/org/surfsite/android/secretshare/ApplicationTest.java index 46a135d..f33f437 100644 --- a/app/src/androidTest/java/org/surfsite/android/secretshare/ApplicationTest.java +++ b/app/src/androidTest/java/org/surfsite/android/secretshare/ApplicationTest.java @@ -36,14 +36,14 @@ public class ApplicationTest extends ApplicationTestCase { SecretShare.PublicInfo pi = null; List si = new ArrayList(); - final BigInteger secretInteger = Renderer.stringToBigInteger(cleartext); + final BigInteger secretInteger = Renderer.stringToSecret(cleartext); final BigInteger modulus; modulus = SecretShare.createAppropriateModulusForSecret(secretInteger); publicInfo = new SecretShare.PublicInfo(n, k, modulus, - "ssss-test"); + "ssss-test€€?=)(/&%$§!#fi#£ ^fỉ)SDGFHKLŒŒflıÓ‚€ƒ€Ω†⁄ø⁄"); final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo) .split(secretInteger); pieces = splitSecretOutput.getShareInfos(); @@ -63,6 +63,7 @@ public class ApplicationTest extends ApplicationTestCase { final SecretShare.CombineOutput combineOutput = new SecretShare(pi) .combine(si); - assertEquals(cleartext, new String(combineOutput.getSecret().toByteArray())); + assertEquals(cleartext, Renderer.secretToString(combineOutput.getSecret())); + assertEquals(publicInfo.getDescription(), si.get(0).getPublicInfo().getDescription()); } } \ No newline at end of file diff --git a/app/src/main/java/org/surfsite/android/secretshare/GenerateFragment.java b/app/src/main/java/org/surfsite/android/secretshare/GenerateFragment.java index 0cd2c25..79027df 100644 --- a/app/src/main/java/org/surfsite/android/secretshare/GenerateFragment.java +++ b/app/src/main/java/org/surfsite/android/secretshare/GenerateFragment.java @@ -1,11 +1,14 @@ package org.surfsite.android.secretshare; import android.app.Activity; +import android.app.AlertDialog; import android.app.Fragment; +import android.content.DialogInterface; import android.graphics.Bitmap; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.support.v4.print.PrintHelper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,7 +19,6 @@ import com.tiemens.secretshare.engine.SecretShare; import com.tiemens.secretshare.engine.SecretShare.ShareInfo; import java.math.BigInteger; -import java.util.ArrayList; import java.util.List; @@ -147,8 +149,6 @@ public class GenerateFragment extends Fragment implements FragmentSupport { private class GenerateSharesTask extends AsyncTask { private final Activity activity; - SecretShare.PublicInfo pi = null; - ShareInfo si[]; private TextView tv; private List pieces; private int n; @@ -158,6 +158,7 @@ public class GenerateFragment extends Fragment implements FragmentSupport { private boolean finished = false; private Bitmap qrCodeBitmap; private ImageView qrCodeView; + private BigInteger secretInteger; public GenerateSharesTask(int n, int k, String cleartext) { activity = getActivity(); @@ -165,9 +166,9 @@ public class GenerateFragment extends Fragment implements FragmentSupport { this.n = n; this.k = k; this.cleartext = cleartext; - si = new ShareInfo[n]; - this.tv.setText("Generating shared secrets for " + cleartext.length() - + " chars. Please Wait. This can take a long time."); + secretInteger = Renderer.stringToSecret(cleartext); + this.tv.setText("Generating shared secrets for " + secretInteger.bitLength() / 8 + + " bytes. Please Wait. This can take a long time."); } public boolean isFinished() { @@ -176,14 +177,14 @@ public class GenerateFragment extends Fragment implements FragmentSupport { @Override protected Void doInBackground(Void... params) { - final BigInteger secretInteger = Renderer.stringToBigInteger(cleartext); + final BigInteger secretInteger = Renderer.stringToSecret(cleartext); final BigInteger modulus; modulus = SecretShare.createAppropriateModulusForSecret(secretInteger); publicInfo = new SecretShare.PublicInfo(n, k, modulus, - null); + "test"); final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo) .split(secretInteger); pieces = splitSecretOutput.getShareInfos(); @@ -207,11 +208,7 @@ public class GenerateFragment extends Fragment implements FragmentSupport { tv.append(out[i] + "\n"); tv.append("B64Len: " + data.length() + "\n"); tv.append(data + "\n"); - if (pi == null) - pi = Renderer.decodePublicInfo(data); - si[n] = Renderer.decodeShareInfo(data, pi); -/* if (i == 0) { View view = activity.getLayoutInflater().inflate(R.layout.address_qr, null); final TextView tv = (TextView) view.findViewById(R.id.secret_text); @@ -234,14 +231,8 @@ public class GenerateFragment extends Fragment implements FragmentSupport { builder.show(); } -*/ + } - List li = new ArrayList(); - li.add(si[0]); - li.add(si[1]); - li.add(si[2]); - final SecretShare.CombineOutput combineOutput = new SecretShare(pi) - .combine(li); this.finished = true; } } diff --git a/app/src/main/java/org/surfsite/android/secretshare/Renderer.java b/app/src/main/java/org/surfsite/android/secretshare/Renderer.java index fc44cc1..43cc7d8 100644 --- a/app/src/main/java/org/surfsite/android/secretshare/Renderer.java +++ b/app/src/main/java/org/surfsite/android/secretshare/Renderer.java @@ -13,10 +13,15 @@ import android.util.Base64; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; -import com.google.zxing.aztec.AztecWriter; import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; import com.tiemens.secretshare.engine.SecretShare; +import org.unicode.scsu.Compress; +import org.unicode.scsu.EndOfInputException; +import org.unicode.scsu.Expand; +import org.unicode.scsu.IllegalInputException; + import java.math.BigInteger; import java.nio.ByteBuffer; import java.security.InvalidParameterException; @@ -24,7 +29,8 @@ import java.util.ArrayList; import java.util.Hashtable; public class Renderer { - private final static AztecWriter sCodeWriter = new AztecWriter(); + // private final static AztecWriter sCodeWriter = new AztecWriter(); + private final static QRCodeWriter sCodeWriter = new QRCodeWriter(); public static Bitmap createBitmap(String data) { final Hashtable hints = @@ -33,12 +39,17 @@ public class Renderer { BitMatrix result; final int size = (int) Math.sqrt(data.length() * 8) * 10; - - result = sCodeWriter.encode(data, - BarcodeFormat.AZTEC, - size, - size, - hints); + try { + result = sCodeWriter.encode(data, + // BarcodeFormat.AZTEC, + BarcodeFormat.QR_CODE, + size, + size, + hints); + } catch (Exception e) { + e.printStackTrace(); + result = null; + } final int width = result.getWidth(); final int height = result.getHeight(); @@ -100,14 +111,6 @@ public class Renderer { @Override protected void onPostExecute(final Bitmap bitmap) { if (bitmap != null) { -//DEBUG -// android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context); -// android.widget.ImageView view = new android.widget.ImageView(context); -// view.setImageBitmap(bitmap); -// builder.setView(view); -// builder.setPositiveButton(android.R.string.ok, null); -// builder.show(); - PrintHelper printHelper = new PrintHelper(context); printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT); printHelper.printBitmap(label, bitmap); @@ -185,16 +188,57 @@ public class Renderer { return lines; } - static BigInteger stringToBigInteger(String in) { - return new BigInteger(in.getBytes()); + + static byte[] tryUnicodeCompress(String in) { + final Compress unicodeCompress = new Compress(); + byte[] bytes = in.getBytes(); + boolean isUTF8 = true; + try { + bytes = unicodeCompress.compress(in); + } catch (IllegalInputException e) { + isUTF8 = false; + } catch (EndOfInputException e) { + isUTF8 = false; + e.printStackTrace(); + } + + byte[] encBytes = new byte[bytes.length + 1]; + System.arraycopy(bytes, 0, encBytes, 0, bytes.length); + encBytes[bytes.length] = (byte) (isUTF8 ? 0 : 1); + return encBytes; + } + + static String tryUnicodeExpand(byte[] in) { + byte[] exBytes = new byte[in.length - 1]; + System.arraycopy(in, 0, exBytes, 0, in.length - 1); + if (in[in.length - 1] == 1) + return new String(exBytes); + final Expand unicodeExpand = new Expand(); + try { + return unicodeExpand.expand(exBytes); + } catch (IllegalInputException e) { + e.printStackTrace(); + } catch (EndOfInputException e) { + e.printStackTrace(); + } + return new String(exBytes); + } + + static BigInteger stringToSecret(String in) { + return new BigInteger(tryUnicodeCompress(in)); + } + + static String secretToString(BigInteger in) { + return tryUnicodeExpand(in.toByteArray()); } public static String encodeShareInfo(final SecretShare.ShareInfo piece) { final SecretShare.PublicInfo publicInfo = piece.getPublicInfo(); final byte[] bytePrimeModulus = publicInfo.getPrimeModulus().toByteArray(); final byte[] byteShare = piece.getShare().toByteArray(); - final byte[] byteDescription = publicInfo.getDescription().getBytes(); - final int byteLen = 4 + 4 + 4 + final byte[] byteDescription = tryUnicodeCompress(publicInfo.getDescription()); + final int byteLen = 4 + + 4 + 4 + (4 + byteDescription.length) + (4 + bytePrimeModulus.length) + (4 + byteShare.length); @@ -213,9 +257,7 @@ public class Renderer { public static SecretShare.PublicInfo decodePublicInfo(final String buf) { int index64 = buf.indexOf("=") + 1; - String substr = buf.substring(index64); - final byte[] decodeBytes = Base64.decode(substr, Base64.DEFAULT); - final ByteBuffer byteBuffer = ByteBuffer.wrap(decodeBytes); + final ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.decode(buf.substring(index64), Base64.DEFAULT)); int x = byteBuffer.getInt(); int k = byteBuffer.getInt(); int n = byteBuffer.getInt(); @@ -223,10 +265,11 @@ public class Renderer { final byte[] byteDescription = new byte[byteDescriptionLength]; byteBuffer.get(byteDescription); int bytePrimeModulusLength = byteBuffer.getInt(); + System.out.printf("len=%d\n", bytePrimeModulusLength); final byte[] bytePrimeModulus = new byte[bytePrimeModulusLength]; byteBuffer.get(bytePrimeModulus); BigInteger inPrimeModulus = new BigInteger(bytePrimeModulus); - return new SecretShare.PublicInfo(n, k, inPrimeModulus, new String(byteDescription)); + return new SecretShare.PublicInfo(n, k, inPrimeModulus, tryUnicodeExpand(byteDescription)); } public static SecretShare.ShareInfo decodeShareInfo(final String buf, final SecretShare.PublicInfo publicInfo) throws InvalidParameterException { @@ -251,7 +294,7 @@ public class Renderer { int byteDescriptionLength = byteBuffer.getInt(); final byte[] byteDescription = new byte[byteDescriptionLength]; byteBuffer.get(byteDescription); - if (publicInfo.getDescription().compareTo(new String(byteDescription)) != 0) { + if (publicInfo.getDescription().compareTo(tryUnicodeExpand(byteDescription)) != 0) { throw new InvalidParameterException("SecretShare.PublicInfo.Description does not match."); } int bytePrimeModulusLength = byteBuffer.getInt();