Implementasi Algoritma Hill Cipher 3x3 dan Rabin Public Key pada Pengiriman Short Message Service (SMS)

A-1

LAMPIRAN A : LISTING PROGRAM
1.

splash.java

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.view.Window;
public class Splash extends Activity {
protected int splash_ = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_splash);
//getSupportActionBar().hide();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

setSplash();
}
public void setSplash() {
new Thread() {
public void run() {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
Intent i = new Intent(Splash.this, MainActivity.class);
Splash.this.finish();
startActivity(i);
}
}.start();
}
}

2.

BuatPesan.java


import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import


android.app.Activity;
android.content.ContentValues;
android.content.Intent;
android.database.Cursor;
android.net.Uri;
android.os.Bundle;
android.provider.ContactsContract;
android.provider.ContactsContract.CommonDataKinds.Phone;
android.telephony.SmsManager;
android.text.TextUtils;
android.util.Log;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.EditText;
android.widget.TextView;
android.widget.Toast;
java.util.Random;

public class BuatPesan extends Activity {

EditText nomorKontak, text, hasilencrypt, kunci_p_enk, kunci_q_enk,
kuncihill_enk, hasilencryptkunci;
TextView pubkey, nilaiK;
// contact picker
private static final int CONTACT_PICKER_RESULT = 1001;
private long waktumulaihill, waktuakhirhill, selisihhill, waktumulairabin;
// phonecontact
public void doLaunchContactPicker(View view) {
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

Universitas Sumatera Utara

A-2

Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
String phone = "";

Cursor contacts = null;
try {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
// gets the uri of selected contact
Uri result = data.getData();
// get the contact id from the Uri (last part is contact
// id)
String id = result.getLastPathSegment();
// queries the contacts DB for phone no
contacts = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone._ID + "=?",
new String[]{id}, null);
// gets index of phone no
int phoneIdx = contacts.getColumnIndex(Phone.DATA);
if (contacts.moveToFirst()) {
// gets the phone no

phone = contacts.getString(phoneIdx);
EditText phoneTxt = (EditText)
findViewById(R.id.nomorHp);
// assigns phone no to EditText field phone number
phoneTxt.setText(phone);
} else {
Toast.makeText(this, "error",
Toast.LENGTH_LONG).show();
}
break;
}
} else {
// gracefully handle failure
Toast.makeText(BuatPesan.this, R.string.belumdipilih,
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
} finally {
if (contacts != null) {

contacts.close();
}
}
}
public String toBinary(long n) {
if (n == 0) {
return "0";
}
String binary = "";
while (n > 0) {
long rem = n % 2;
binary = rem + binary;
n = n / 2;
}
return binary;
}
public long toDecimal(long binary) {
long decimal = 0;
long power = 0;
while (true) {

if (binary == 0) {
break;
} else {

Universitas Sumatera Utara

A-3

long temp = binary % 10;
decimal += temp * Math.pow(2, power);
binary = binary / 10;
power++;
}
}
return decimal;
}
public boolean fermat(int p) {
boolean hasil = true;
Random rand = new Random();
int a = rand.nextInt(20) + 1;

if (a % p == 0) {
hasil = false;
} else if (modExp(a, p - 1, p) != 1) {
hasil = false;
}
return hasil;
}
public static int modExp(int a, int b, int n) {
if (b == 0) return 1;
long t = modExp(a, b / 2, n);
long c = (t * t) % n;
if (b % 2 == 1)
c = (c * a) % n;
return (int) c;
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("Encrypt Message");
setContentView(R.layout.buatpesan);

final Button send = (Button) findViewById(R.id.send);
final Button encrypt = (Button) findViewById(R.id.encrypt);
final Button encryptkunci = (Button) findViewById(R.id.encryptkunci);
text = (EditText) findViewById(R.id.smsBox);
nomorKontak = (EditText) findViewById(R.id.nomorHp);
hasilencrypt = (EditText) findViewById(R.id.hasilEncrypt);
hasilencryptkunci = (EditText) findViewById(R.id.hasilEncryptkunci);
kunci_p_enk = (EditText) findViewById(R.id.kunci_p_enk);
kunci_q_enk = (EditText) findViewById(R.id.kunci_q_enk);
kuncihill_enk = (EditText) findViewById(R.id.KunciHill_enk);
pubkey = (TextView) findViewById(R.id.pubkey);
nilaiK = (TextView) findViewById(R.id.Kvalues);
Intent i = getIntent();
if (i.getStringExtra("message") != null) {
text.setText(i.getStringExtra("message"));
}
encryptkunci.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

waktumulairabin = System.currentTimeMillis();
String enkunciaes = "";
String keyx = kuncihill_enk.getText().toString();
String p = kunci_p_enk.getText().toString();
String q = kunci_q_enk.getText().toString();
try {
if (TextUtils.isEmpty(keyx)) {
kuncihill_enk.setError("Your key is Empty");
} else if (TextUtils.isEmpty(p)) {
kunci_p_enk.setError("Private Keys cannot Empty");
} else if (TextUtils.isEmpty(q)) {
kunci_q_enk.setError("Private Keys cannot Empty");
} else if (!p.matches("[0-9]*")) {
kunci_p_enk.setError("Private Keys must be a Number");

Universitas Sumatera Utara

A-4

} else if (!q.matches("[0-9]*")) {
kunci_q_enk.setError("Private Keys must be a Number");
} else if (p.equals(q)) {
kunci_p_enk.setError("Private Keys must be Different");
} else if (!fermat(Integer.parseInt(p))) {
kunci_p_enk.setError("Private Key must be a Prime
Number");
} else if (!fermat(Integer.parseInt(q))) {
kunci_q_enk.setError("Private Key must be a Prime
Number");
} else if (Integer.parseInt(p) % 4 != 3) {
kunci_p_enk.setError("Private Keys must have modulus 3
when devide by 4");
} else if (Integer.parseInt(q) % 4 != 3) {
kunci_q_enk.setError("Private Keys must have modulus 3
when devide by 4");
} else {
long startTime = System.currentTimeMillis();
int uvw = Integer.parseInt(p);
int xyz = Integer.parseInt(q);
long publickey = uvw * xyz;
pubkey.setText("public key :" + publickey);
//tabelEnc obj1 = new tabelEnc();
for (int i = 0; i < keyx.length(); ++i) {
//Toast.makeText(getApplicationContext(), "ke:
"+i+"ms", Toast.LENGTH_LONG).show();
char b = keyx.charAt(i);
int plain = tabelEnc.getIndex(b);
String double_text = toBinary(plain) +
toBinary(plain);
long double_dectext = Long.parseLong(double_text);
long m = toDecimal(double_dectext);
long k = (m - (m % publickey)) / publickey;
nilaiK.setText(nilaiK.getText() + " " + k);
SimpanKunci.setKkey(String.valueOf(k));
long c = (long) (Math.pow(m, 2) % publickey);
SimpanKunci.setCipherkey(String.valueOf(c));
hasilencryptkunci.setText(hasilencryptkunci.getText()
+ " " + c);
}
// obj2 = new simpanVariabel();
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);
Toast.makeText(getApplicationContext(), "Encryption Time:
" + duration + "ms", Toast.LENGTH_LONG).show();
}
} catch (Exception e1) {
Toast.makeText(BuatPesan.this, enkunciaes,
Toast.LENGTH_LONG).show();
e1.printStackTrace();
}
//hasilencryptkunci.setText(enkunciaes);
}
});
encrypt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View e) {
String ambilKata = text.getText().toString();
String kunci_enk_hill = kuncihill_enk.getText().toString();
String enKata = "";
try {
if ((kuncihill_enk.getText().toString().equals("") ||
text.getText().toString().equals(""))) {
Toast.makeText(BuatPesan.this, "Pesan ataupun kunci tidak
boleh kosong",
Toast.LENGTH_SHORT).show();
} else {
//String hasil1=null;

Universitas Sumatera Utara

A-5

waktumulaihill = System.currentTimeMillis();
hillCipher obj = new hillCipher();
double sq = Math.sqrt(kunci_enk_hill.length());
System.out.println("ini double " + sq + " ini long " +
(long) sq + " ini int " + (int) sq);
if (sq != (long) sq)
System.out.println("panjang kunci salah");
//0+3TLeT*9[I.MV5hk1z%z mOTR$QB>U
else {
int s = (int) sq;
if (obj.check(kunci_enk_hill, s)) {
System.out.println("Result:");
obj.divide(ambilKata, s);
//pakai kunci ASCII
dari 32-126
System.out.println("ini ya guys :" +
obj.hasilenkripsi);
Log.i("Kata Asal", ambilKata);
enKata = obj.hasilenkripsi;
Log.i("Kata Hasil", enKata);
obj.cofact(obj.keymatrix, s);
System.out.print("inversi key " + obj.invkey);
}
}
hasilencrypt.setText(enKata);
waktuakhirhill = System.currentTimeMillis();
selisihhill = waktuakhirhill - waktumulaihill;
Toast.makeText(BuatPesan.this, "lama enkripsi Hill Cipher
" + Long.toString(selisihhill), Toast.LENGTH_SHORT).show();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
send.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String pesan = hasilencrypt.getText().toString();
String nomor = nomorKontak.getText().toString();
if (pesan.length() > 0 && nomor.length() > 0) {
try {
// proses kirim sms
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(nomor, null, pesan, null, null);
// proses simpan sms yang terkirim
ContentValues values = new ContentValues();
values.put("address", nomor);
values.put("body", pesan);
getContentResolver().insert(
Uri.parse("content://sms/sent"), values);
Toast.makeText(BuatPesan.this,
"Pesan berhasil dikirim", Toast.LENGTH_SHORT)
.show();
finish();
} catch (Exception e) {
Toast.makeText(BuatPesan.this, "Pesan gagal dikirim",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
} else {
Toast.makeText(BuatPesan.this,
"Nomor atau Isi Pesan Masing Kosong",
Toast.LENGTH_SHORT).show();
}
}
});
}
}

Universitas Sumatera Utara

A-6

3.

LihatPesan.java

import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.DialogInterface;
android.content.Intent;
android.net.Uri;
android.os.Bundle;
android.util.Log;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.EditText;
android.widget.TextView;
android.widget.Toast;
java.nio.charset.Charset;
java.util.Random;

public class LihatPesan extends Activity {
private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
final int tipe_enkripsi=128;
private long
selisihhill,waktuawalhill,waktuakhirhill,selisihrabin,waktuawalrabin,waktuakhirrab
in,selisihtotal;
TextView number, date, msg,hasilDekripsi;
Button forward, hapus,dekripsi,dekripsikunci,btndekriphill;
EditText kunci_p_dek,kunci_q_dek,nilai_k,kuncihill_Dek,hasildekkuncihill;
public boolean pil_rad=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lihatpesan);
this.setTitle("Decrypt Message");
number = (TextView) findViewById(R.id.tvNumber);
date = (TextView) findViewById(R.id.tvDate);
msg = (TextView) findViewById(R.id.tvMsg);
hasilDekripsi = (TextView) findViewById(R.id.hasildekrip);
dekripsi = (Button) findViewById(R.id.dekripsiBtn);
forward = (Button) findViewById(R.id.btFrd);
btndekriphill=(Button) findViewById(R.id.btnDekripkunci);
hapus = (Button) findViewById(R.id.hapus);
kunci_p_dek = (EditText) findViewById(R.id.kunci_p_dek);
kunci_q_dek = (EditText) findViewById(R.id.kunci_q_dek);
hasildekkuncihill=(EditText) findViewById(R.id.hasildekkuncihill);
kuncihill_Dek = (EditText) findViewById(R.id.kuncihill_dek);
nilai_k = (EditText)findViewById(R.id.k_values);
kuncihill_Dek.setText(SimpanKunci.getCipherkey());
nilai_k.setText(SimpanKunci.getKkey());
btndekriphill.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
int a_inv = 0;
int flag = 0;
waktuawalrabin=System.currentTimeMillis();
String ambilkata2 = kuncihill_Dek.getText().toString();
String kunci_dek = kunci_p_dek.getText().toString();
String temp="";
String hasil2 = null;
try {
String keyx = SimpanKunci.getCipherkey();
String p = kunci_p_dek.getText().toString();
String q = kunci_q_dek.getText().toString();
String k = SimpanKunci.getKkey();
if ("".equals(keyx)) {
kuncihill_Dek.setError("Your Cipherkey is Empty");
} else if ("".equals(p)) {
kunci_p_dek.setError("Private Keys cannot Empty");

Universitas Sumatera Utara

A-7

} else if ("".equals(q)) {
kunci_q_dek.setError("Private Keys cannot Empty");
} else if (p.equals(q)) {
kunci_p_dek.setError("Private Keys must be Different");
} else if (!p.matches("[0-9]*")) {
kunci_p_dek.setError("Private Keys must be a Number");
} else if (!q.matches("[0-9]*")) {
kunci_q_dek.setError("Private Keys must be a Number");
} else if (!fermat(Integer.parseInt(p))) {
kunci_p_dek.setError("Private Key must be a Prime
Number");
} else if (!fermat(Integer.parseInt(q))) {
kunci_q_dek.setError("Private Key must be a Prime
Number");
} else if (Integer.parseInt(p) % 4 != 3) {
kunci_p_dek.setError("Private Keys must have modulus 3
when devide by 4");
} else if (Integer.parseInt(q) % 4 != 3) {
kunci_q_dek.setError("Private Keys must have modulus 3
when devide by 4");
} else if ("".equals(k)) {
nilai_k.setError("K cannot Empty");
}else {
long startTime=System.currentTimeMillis();
int uvw = Integer.parseInt(p);
int xyz = Integer.parseInt(q);
int n = uvw * xyz;
int P = (uvw + 1) / 4;
int Q = (xyz + 1) / 4;
int vals[] = gcd(uvw, xyz);
int Yp = vals[1];
int Yq = vals[2];
int r, s, t, u, R, S, T, U;
String[] cipherteks = keyx.split(" ");
int[] arrayCiptext = new int[cipherteks.length];
String[] Kvalues = k.split(" ");
int[] arrayK = new int[Kvalues.length];
for (int i = 0; i < cipherteks.length; i++) {
try {
arrayCiptext[i] = Integer.parseInt(cipherteks[i]);
arrayK[i] = Integer.parseInt(Kvalues[i]);
} catch (NumberFormatException nfe) {
}
int cipher = arrayCiptext[i];
int K = arrayK[i];
double mp = modExp(cipher, P, uvw);
double mq = modExp(cipher, Q, xyz);
int a1 = (int) (Yp * uvw * mq);
int a2 = (int) (Yq * xyz * mp);
r = ((a1 + a2) % n + n) % n;
R = (K * n) + r;
String Rx = toBinary(R);
s = ((a1 - a2) % n + n) % n;
S = (K * n) + s;
String Sx = toBinary(S);
t = ((-a1 + a2) % n + n) % n;
T = (K * n) + t;
String Tx = toBinary(T);
u = ((-a1 - a2) % n + n) % n;
U = (K * n) + u;
String Ux = toBinary(U);
//tabelEnc tabelEnc= new tabelEnc();
char hsl;
if (check(Rx)) {
String RR = singlebin(Rx);
long Rfinal = Long.parseLong(RR);
long Rfin = toDecimal(Rfinal);
hsl=tabelEnc.getChar((int)Rfin);
hasildekkuncihill.setText(hasildekkuncihill.getText().toString() + hsl);
} else if (check(Sx)) {
String SS = singlebin(Sx);

Universitas Sumatera Utara

A-8

long Sfinal = Long.parseLong(SS);
long Sfin = toDecimal(Sfinal);
hsl=tabelEnc.getChar((int)Sfin);
hasildekkuncihill.setText(hasildekkuncihill.getText().toString() + hsl);
} else if (check(Tx)) {
String TT = singlebin(Tx);
long Tfinal = Long.parseLong(TT);
long Tfin = toDecimal(Tfinal);
hsl=tabelEnc.getChar((int)Tfin);
hasildekkuncihill.setText(hasildekkuncihill.getText().toString() + hsl);
} else if (check(Ux)) {
String UU = singlebin(Ux);
long Ufinal = Long.parseLong(UU);
long Ufin = toDecimal(Ufinal);
hsl=tabelEnc.getChar((int)Ufin);
hasildekkuncihill.setText(hasildekkuncihill.getText().toString() + hsl);
} else {
hasildekkuncihill.setText("");
}
}
//DekripsiAutokeyCipher(msgx, key.getText().toString());
long endTime=System.currentTimeMillis();
long duration = (endTime - startTime);
SimpanKunci.Reset();
Toast.makeText(getApplicationContext(), "Decryption Time:
"+duration+"ms", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//hasildekkunciaes.setText(temp);
waktuakhirrabin=System.currentTimeMillis();
selisihrabin=waktuakhirrabin-waktuawalrabin;
Toast.makeText(LihatPesan.this, "lama dekripsi rabin
"+Long.toString(selisihrabin),Toast.LENGTH_SHORT).show();
}
});
dekripsi.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
int a_inv = 0;
int flag = 0;
String ambilKata = msg.getText().toString();
String deKata = "";
try {
if (!"".equals(hasildekkuncihill.getText().toString())) {
waktuawalhill=System.currentTimeMillis();
String hasil2e=null;
String keyaes_dek =
hasildekkuncihill.getText().toString();
hillCipher obj1 = new hillCipher();
double sq = Math.sqrt(keyaes_dek.length());
System.out.println("ini double "+sq+" ini long
"+(long)sq+" ini int "+(int)sq);
if (sq != (long) sq)
System.out.println("panjang kunci salah");
//0+3TLeT*9[I.MV5hk1z%z mOTR$QB>U
else
{
int s = (int) sq;
if (obj1.check(keyaes_dek, s))
{
System.out.println("Result:");
obj1.cofact(obj1.keymatrix, s);
System.out.print("inversi key "+obj1.invkey);
keyaes_dek=obj1.invkey;

Universitas Sumatera Utara

A-9

}
}
double sqt = Math.sqrt(keyaes_dek.length());
System.out.println("ini double "+sq+" ini long
"+(long)sq+" ini int "+(int)sq);
if (sqt != (long) sqt)
System.out.println("panjang kunci salah");
//0+3TLeT*9[I.MV5hk1z%z mOTR$QB>U
else
{
int s = (int) sqt;
if (obj1.check(keyaes_dek, s))
{
System.out.println("Result:");
obj1.divide(ambilKata, s);
//pakai kunci ASCII
dari 32-126
System.out.println("ini ya wee
:"+obj1.hasilenkripsi);
deKata=obj1.hasilenkripsi;
obj1.cofact(obj1.keymatrix, s);
System.out.print("inversi key "+obj1.invkey);
}
}
waktuakhirhill=System.currentTimeMillis();
hasilDekripsi.setText(deKata);
selisihhill=(waktuakhirhill-waktuawalhill);
selisihtotal=selisihhill+selisihrabin;
Toast.makeText(LihatPesan.this, "waktu dekrips Hill Cipher
"+Long.toString(selisihtotal),Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(LihatPesan.this, "PlainText Kunci Hill
masih kosong",Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.i("Error", e.getMessage());hasilDekripsi.setText("kunci
tidak memenuhi GCD atau tidak memenuhi syarat inversi modulo ");}
}
});
}
@Override
protected void onStart() {
super.onStart();
Intent i = getIntent();
number.setText(i.getStringExtra("no"));
date.setText(i.getStringExtra("date"));
msg.setText(i.getStringExtra("msg"));
forward.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent click = new Intent(LihatPesan.this, BuatPesan.class);
click.putExtra("message", msg.getText());
startActivity(click);
}
});
hapus.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Dialogs.showConfirmation(LihatPesan.this,
R.string.hapuspesan_dialog,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
Intent i = getIntent();
String id_pesan_hapus = i
.getStringExtra("idpesan");

Universitas Sumatera Utara

A-10

String id_thread_hapus = i
.getStringExtra("idthread");
// hapus pesan
Uri deleteUri = Uri.parse("content://sms");
getContentResolver()
.delete(deleteUri,
"thread_id=? and _id=?",
new String[] {
String.valueOf(id_thread_hapus),
String.valueOf(id_pesan_hapus) });
finish();
Toast.makeText(LihatPesan.this,
"Pesan Terhapus", Toast.LENGTH_SHORT)
.show();
// redirect data pesan
onBackPressed();
}
});
}
});
}
public String toBinary(long n) {
if (n == 0) {
return "0";
}
String binary = "";
while (n > 0) {
long rem = n % 2;
binary = rem + binary;
n = n / 2;
}
return binary;
}
public long toDecimal(long binary){
long decimal = 0;
long power = 0;
while(true){
if(binary == 0){
break;
} else {
long temp = binary%10;
decimal += temp*Math.pow(2, power);
binary = binary/10;
power++;
}
}
return decimal;
}
public static int[] gcd(int p, int q) {
if (q==0)
return new int[] { p, 1, 0 };
int[] vals = gcd(q, p % q);
int d = vals[0];
int a = vals[2];
int b = vals[1] - (p / q) * vals[2];
return new int[] { d, a, b };
}
public static int modExp(int a, int b, int n) {
if (b == 0) return 1;
long t = modExp(a, b/2, n);
long c = (t*t)%n;
if (b%2 == 1)
c = (c*a)%n;

Universitas Sumatera Utara

A-11

return (int)c;
}
public boolean check(String x){
boolean hsl = true;
int a = Math.round(x.length()/2);
for(int i=0; i