add Unicode compressions marker

This commit is contained in:
Harald Hoyer 2014-07-31 15:35:04 +02:00
parent cdbb309f4d
commit 031b7ebb0a
3 changed files with 82 additions and 47 deletions

View file

@ -36,14 +36,14 @@ public class ApplicationTest extends ApplicationTestCase<Application> {
SecretShare.PublicInfo pi = null; SecretShare.PublicInfo pi = null;
List<SecretShare.ShareInfo> si = new ArrayList<SecretShare.ShareInfo>(); List<SecretShare.ShareInfo> si = new ArrayList<SecretShare.ShareInfo>();
final BigInteger secretInteger = Renderer.stringToBigInteger(cleartext); final BigInteger secretInteger = Renderer.stringToSecret(cleartext);
final BigInteger modulus; final BigInteger modulus;
modulus = SecretShare.createAppropriateModulusForSecret(secretInteger); modulus = SecretShare.createAppropriateModulusForSecret(secretInteger);
publicInfo = new SecretShare.PublicInfo(n, publicInfo = new SecretShare.PublicInfo(n,
k, k,
modulus, modulus,
"ssss-test"); "ssss-test€€?=)(/&%$§!#fi#£ ^fỉ)SDGFHKLŒŒflıÓ€ƒ€Ω†ø");
final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo) final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo)
.split(secretInteger); .split(secretInteger);
pieces = splitSecretOutput.getShareInfos(); pieces = splitSecretOutput.getShareInfos();
@ -63,6 +63,7 @@ public class ApplicationTest extends ApplicationTestCase<Application> {
final SecretShare.CombineOutput combineOutput = new SecretShare(pi) final SecretShare.CombineOutput combineOutput = new SecretShare(pi)
.combine(si); .combine(si);
assertEquals(cleartext, new String(combineOutput.getSecret().toByteArray())); assertEquals(cleartext, Renderer.secretToString(combineOutput.getSecret()));
assertEquals(publicInfo.getDescription(), si.get(0).getPublicInfo().getDescription());
} }
} }

View file

@ -1,11 +1,14 @@
package org.surfsite.android.secretshare; package org.surfsite.android.secretshare;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment; import android.app.Fragment;
import android.content.DialogInterface;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.print.PrintHelper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -16,7 +19,6 @@ import com.tiemens.secretshare.engine.SecretShare;
import com.tiemens.secretshare.engine.SecretShare.ShareInfo; import com.tiemens.secretshare.engine.SecretShare.ShareInfo;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -147,8 +149,6 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
private class GenerateSharesTask extends AsyncTask<Void, Void, Void> { private class GenerateSharesTask extends AsyncTask<Void, Void, Void> {
private final Activity activity; private final Activity activity;
SecretShare.PublicInfo pi = null;
ShareInfo si[];
private TextView tv; private TextView tv;
private List<SecretShare.ShareInfo> pieces; private List<SecretShare.ShareInfo> pieces;
private int n; private int n;
@ -158,6 +158,7 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
private boolean finished = false; private boolean finished = false;
private Bitmap qrCodeBitmap; private Bitmap qrCodeBitmap;
private ImageView qrCodeView; private ImageView qrCodeView;
private BigInteger secretInteger;
public GenerateSharesTask(int n, int k, String cleartext) { public GenerateSharesTask(int n, int k, String cleartext) {
activity = getActivity(); activity = getActivity();
@ -165,9 +166,9 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
this.n = n; this.n = n;
this.k = k; this.k = k;
this.cleartext = cleartext; this.cleartext = cleartext;
si = new ShareInfo[n]; secretInteger = Renderer.stringToSecret(cleartext);
this.tv.setText("Generating shared secrets for " + cleartext.length() this.tv.setText("Generating shared secrets for " + secretInteger.bitLength() / 8
+ " chars. Please Wait. This can take a long time."); + " bytes. Please Wait. This can take a long time.");
} }
public boolean isFinished() { public boolean isFinished() {
@ -176,14 +177,14 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
final BigInteger secretInteger = Renderer.stringToBigInteger(cleartext); final BigInteger secretInteger = Renderer.stringToSecret(cleartext);
final BigInteger modulus; final BigInteger modulus;
modulus = SecretShare.createAppropriateModulusForSecret(secretInteger); modulus = SecretShare.createAppropriateModulusForSecret(secretInteger);
publicInfo = new SecretShare.PublicInfo(n, publicInfo = new SecretShare.PublicInfo(n,
k, k,
modulus, modulus,
null); "test");
final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo) final SecretShare.SplitSecretOutput splitSecretOutput = new SecretShare(publicInfo)
.split(secretInteger); .split(secretInteger);
pieces = splitSecretOutput.getShareInfos(); pieces = splitSecretOutput.getShareInfos();
@ -207,11 +208,7 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
tv.append(out[i] + "\n"); tv.append(out[i] + "\n");
tv.append("B64Len: " + data.length() + "\n"); tv.append("B64Len: " + data.length() + "\n");
tv.append(data + "\n"); tv.append(data + "\n");
if (pi == null)
pi = Renderer.decodePublicInfo(data);
si[n] = Renderer.decodeShareInfo(data, pi);
/*
if (i == 0) { if (i == 0) {
View view = activity.getLayoutInflater().inflate(R.layout.address_qr, null); View view = activity.getLayoutInflater().inflate(R.layout.address_qr, null);
final TextView tv = (TextView) view.findViewById(R.id.secret_text); final TextView tv = (TextView) view.findViewById(R.id.secret_text);
@ -234,14 +231,8 @@ public class GenerateFragment extends Fragment implements FragmentSupport {
builder.show(); builder.show();
} }
*/
} }
List<ShareInfo> li = new ArrayList<ShareInfo>();
li.add(si[0]);
li.add(si[1]);
li.add(si[2]);
final SecretShare.CombineOutput combineOutput = new SecretShare(pi)
.combine(li);
this.finished = true; this.finished = true;
} }
} }

View file

@ -13,10 +13,15 @@ import android.util.Base64;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType; import com.google.zxing.EncodeHintType;
import com.google.zxing.aztec.AztecWriter;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.tiemens.secretshare.engine.SecretShare; 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.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.InvalidParameterException; import java.security.InvalidParameterException;
@ -24,7 +29,8 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
public class Renderer { 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) { public static Bitmap createBitmap(String data) {
final Hashtable<EncodeHintType, Object> hints = final Hashtable<EncodeHintType, Object> hints =
@ -33,12 +39,17 @@ public class Renderer {
BitMatrix result; BitMatrix result;
final int size = (int) Math.sqrt(data.length() * 8) * 10; final int size = (int) Math.sqrt(data.length() * 8) * 10;
try {
result = sCodeWriter.encode(data, result = sCodeWriter.encode(data,
BarcodeFormat.AZTEC, // BarcodeFormat.AZTEC,
BarcodeFormat.QR_CODE,
size, size,
size, size,
hints); hints);
} catch (Exception e) {
e.printStackTrace();
result = null;
}
final int width = result.getWidth(); final int width = result.getWidth();
final int height = result.getHeight(); final int height = result.getHeight();
@ -100,14 +111,6 @@ public class Renderer {
@Override @Override
protected void onPostExecute(final Bitmap bitmap) { protected void onPostExecute(final Bitmap bitmap) {
if (bitmap != null) { 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 printHelper = new PrintHelper(context);
printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT); printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
printHelper.printBitmap(label, bitmap); printHelper.printBitmap(label, bitmap);
@ -185,16 +188,57 @@ public class Renderer {
return lines; 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) { public static String encodeShareInfo(final SecretShare.ShareInfo piece) {
final SecretShare.PublicInfo publicInfo = piece.getPublicInfo(); final SecretShare.PublicInfo publicInfo = piece.getPublicInfo();
final byte[] bytePrimeModulus = publicInfo.getPrimeModulus().toByteArray(); final byte[] bytePrimeModulus = publicInfo.getPrimeModulus().toByteArray();
final byte[] byteShare = piece.getShare().toByteArray(); final byte[] byteShare = piece.getShare().toByteArray();
final byte[] byteDescription = publicInfo.getDescription().getBytes(); final byte[] byteDescription = tryUnicodeCompress(publicInfo.getDescription());
final int byteLen = 4 + 4 + 4 final int byteLen = 4
+ 4 + 4
+ (4 + byteDescription.length) + (4 + byteDescription.length)
+ (4 + bytePrimeModulus.length) + (4 + bytePrimeModulus.length)
+ (4 + byteShare.length); + (4 + byteShare.length);
@ -213,9 +257,7 @@ public class Renderer {
public static SecretShare.PublicInfo decodePublicInfo(final String buf) { public static SecretShare.PublicInfo decodePublicInfo(final String buf) {
int index64 = buf.indexOf("=") + 1; int index64 = buf.indexOf("=") + 1;
String substr = buf.substring(index64); final ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.decode(buf.substring(index64), Base64.DEFAULT));
final byte[] decodeBytes = Base64.decode(substr, Base64.DEFAULT);
final ByteBuffer byteBuffer = ByteBuffer.wrap(decodeBytes);
int x = byteBuffer.getInt(); int x = byteBuffer.getInt();
int k = byteBuffer.getInt(); int k = byteBuffer.getInt();
int n = byteBuffer.getInt(); int n = byteBuffer.getInt();
@ -223,10 +265,11 @@ public class Renderer {
final byte[] byteDescription = new byte[byteDescriptionLength]; final byte[] byteDescription = new byte[byteDescriptionLength];
byteBuffer.get(byteDescription); byteBuffer.get(byteDescription);
int bytePrimeModulusLength = byteBuffer.getInt(); int bytePrimeModulusLength = byteBuffer.getInt();
System.out.printf("len=%d\n", bytePrimeModulusLength);
final byte[] bytePrimeModulus = new byte[bytePrimeModulusLength]; final byte[] bytePrimeModulus = new byte[bytePrimeModulusLength];
byteBuffer.get(bytePrimeModulus); byteBuffer.get(bytePrimeModulus);
BigInteger inPrimeModulus = new BigInteger(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 { 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(); int byteDescriptionLength = byteBuffer.getInt();
final byte[] byteDescription = new byte[byteDescriptionLength]; final byte[] byteDescription = new byte[byteDescriptionLength];
byteBuffer.get(byteDescription); 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."); throw new InvalidParameterException("SecretShare.PublicInfo.Description does not match.");
} }
int bytePrimeModulusLength = byteBuffer.getInt(); int bytePrimeModulusLength = byteBuffer.getInt();