Java ME : Algoritma Kriptografi Elliptic Curve Cryptography (ECC) - Elang Sakti
Download Ebook Belajar Arduino PDF, Arduino untuk pemula
Jasa Pembuatan Program Arduino, pemrograman Arduino
# Hack Your Skills! to be Professional Mechatronics

Java ME : Algoritma Kriptografi Elliptic Curve Cryptography (ECC)

3 komentar
Dibawah ini adalah algoritma kriptografi kurva eliptik (ECC) dalam basaha java, khususnya J2ME. Pada kelas tersebut ada fungsi-fungsi yang sengaja dibuat untuk melengkapi kekurangan di J2ME, misalnya fungsi Split() untuk memecah string, sementara di J2ME fungsi untuk memecah string tidak ada. Kemudian fungsi powSqrt() sebagai fungsi perpangkatan sebagai pengganti fungsi Math.pow() yang ada juga di J2ME.
  • Fungsi isCurve() itu berguna untuk memeriksa apakah pasangan a, b, dan bilangan prima sudah sesuai dengan persamaan kurva eliptik yaitu y^2 = x^3+ax+b.
  • Funsi isPrime() untuk memeriksa apakah angka acak yang akan digunakan termasuk bilangan prima atau bukan.
  • Fungsi titik() untuk mencari titik-titik yang sesuai dengan persamaan sesua variabel a, b, dan bilangan prima yang ditentukan.
  • Fungsi arrAdd() sebagai tool agar proses penambahan array integer lebih mudah.
  • Fungsi invers() untuk mencari nilai invers dari suatu bilangan.
  • Fungsi kali() untuk implementasi aturan perkalian titik pada kurva eliptik.
  • Fungsi jumlah() untuk implementasi aturan penjumlah titik pada kurva eliptik.

Fungsi-fungsi di atas mengacu pada perhitungan pada posting sebelumnya :

import java.util.Vector;

/**
 *
 * @author x86
 */
public class Curve {

    /**
     * @param args the command line arguments
     */
    
    public static void main(String[] args) {
        
        //fungsi y^2 = x^3+ax+b
        int a = 1;
        int b = 1;
        System.out.println("Persamaan yang dipakai y^2 = x^3+x+1");
        
        //bilangan prima (random sesuai persamaan)
        int p = 193;
        System.out.println("Bilangan Prima (acak random) p="+p);
        
        //System.out.println();
        System.out.println("Anggota Himpunan di atas dengan batas atas bilangan prima "+p);
        for(int x=0; x<p; x++){
            titik(p,a,b,x);
        }
        System.out.println();
        
        // key (random sesuai persamaan)
        int k = 4;
        System.out.println("Privat key k (untuk penerima) = "+k);
        
        // titik awal (random sesuai persamaan)
        int[] P = {133,78};
        System.out.println("Titik awal kurva  P = ("+P[0]+","+P[1]+")");
        
        // key public penerima (random sesuai persamaan)
        System.out.println("Public Key k.P, dihitung dengan cara mengalikan private key k ke titik awal kurva P");
        System.out.println("k*P = "+k+"*("+P[0]+","+P[1]+")");
        int[] dP = kali(p,a,b,k,P);
        System.out.println("Jadi, Public Key k.P = ("+dP[0]+","+dP[1]+")");
        System.out.println("Catatan : Perkalian dan perhitungan titik kurva menggunakan aturan");
        System.out.println("Perkalian, penjumlahan, penggandaan, dan invers,");
        System.out.println("Jadi perkaliannya tidak sama denga perkalian matriks.");
        
        String pesan = "haripinter";
        System.out.println("Pesan yang akan di enkripsi : "+pesan);
        System.out.println();
        
        System.out.println("Proses Enkripsi :");
        System.out.println("-----------------------");
        String str = enkrip(P,dP,pesan,k,a,b,p);
        
        System.out.println();
        System.out.println("Proses Dekripsi :");
        System.out.println("-----------------------");
        String msg = dekrip(str,k,a,b,p);
    }
    
    static String enkrip(int[] P, int[] dP, String M, int k, int a, int b, int p){
        System.out.println("- Menentukan titik kkP sebagai titik pengenkripsi.");
        System.out.println("k*kP = "+k+"*"+"("+dP[0]+","+dP[1]+")");
        int[] kdP = kali(p, a, b, k, dP);
        System.out.println("Titik kkP : ("+kdP[0]+","+kdP[1]+")");
        System.out.println();
        int XkdP = kdP[0];
        
        System.out.println("- Menentukan titik Awal proses dekripsi.");
        System.out.println("k*P = "+k+"*"+" ("+P[0]+","+P[1]+")");
        int[] kP = kali(p, a, b, k, P);
        System.out.println("Titik kP : ("+kP[0]+","+kP[1]+")");
        System.out.println();
        
        String head = (char)kP[0]+"#"+(char)kP[1]+"#";
        System.out.println("Header titik kP dijadikan karakter kemudian disertakan dalam pesan (bisa jadi karakternya tidak tampak) : "+head);
        System.out.println();
        
        System.out.println("Ambil titik absis kkP untuk di-xor-kan ke pesan.");
        System.out.println(XkdP+" -> "+Integer.toBinaryString(XkdP));
        System.out.println();
        
        System.out.println("Konversi pesan ke integer sesuai format ASCII, kemudian jadikan biner. Selanjutnya di xor dengan absis titik kdP.");
        System.out.println("Setelah di xor, rangkai lagi menjadi pesan baru yang terenkripsi:");
        String MM="";
        for(int cd=0; cd<M.length(); cd++){
            System.out.print(M.charAt(cd)+" -> "+(int)M.charAt(cd)+" -> "+Integer.toBinaryString((int)M.charAt(cd)));
            int eMx = XkdP ^ M.charAt(cd);
            System.out.println(" xor "+Integer.toBinaryString(XkdP)+" => "+eMx+" ("+(char)eMx+")");
            MM = MM + (char)eMx;
        }
        System.out.println("Angka desimal pesan diatas kemudian dikembalikan menjadi karakter");
        System.out.println("Pesan Baru terenkripsi : "+MM);
        MM = head + MM;
        
        System.out.println("header + Pesan Baru terenkripsi : "+MM);
        return MM;
    }
    
    static String dekrip(String M, int d, int a, int b, int p){
        System.out.println("Pesan terenkripsi : "+M);
        System.out.println("Pisahkan header dan pesan asli. Kemudian ambil ke titik kp:");
        String msg = "";
        String[] dmp = Split(M,"#");
        
        if(dmp.length!=3) return M;
        
        // kp[0]#kp[1]
        int[] kP = {(int)dmp[0].charAt(0),(int)dmp[1].charAt(0)};
        System.out.println("Titik kP : ("+kP[0]+","+kP[1]+")");
        System.out.println();
        System.out.println("Hitung titik kP dengan k untuk mendapatkan titik-titik pesan");
        System.out.println(d+"*("+kP[0]+","+kP[1]+")");
        int[] dkP = kali(p,a,b,d,kP);
        System.out.println("Titik kkP : ("+dkP[0]+","+dkP[1]+")");
        System.out.println();
        
        System.out.println("Ambil titik absis kkP untuk di-xor-kan ke pesan terenkripsi.");
         System.out.println(dkP[0]+" -> "+Integer.toBinaryString(dkP[0]));
        System.out.println();
        System.out.println("Ambil pesan perkarakter, jadikan biner, kemudian xor-kan ke kkP");
        M = dmp[2];
        for(int dr=0; dr<M.length(); dr++){
            System.out.print(M.charAt(dr)+" -> "+(int)M.charAt(dr)+" -> "+Integer.toBinaryString((int)M.charAt(dr)));
            int eMX = dkP[0] ^ M.charAt(dr);
            System.out.println(" xor "+Integer.toBinaryString(dkP[0])+" => "+eMX+" ("+(char)eMX+")");
            msg = msg + (char) eMX;
        }
        
        System.out.println();
        System.out.println("Rangkai kembali menjadi pesan asli.");
        System.out.println(msg);
        return msg;
    }
    
    public static String[] Split(String splitStr, String delimiter) {
     StringBuffer token = new StringBuffer();
     Vector tokens = new Vector();
     // split
     char[] chars = splitStr.toCharArray();
     for (int i=0; i < chars.length; i++) {
         if (delimiter.indexOf(chars[i]) != -1) {
             // we bumbed into a delimiter
             if (token.length() > 0) {
                 tokens.addElement(token.toString());
                 token.setLength(0);
             }
         } else {
             token.append(chars[i]);
         }
     }
     // don't forget the "tail"...
     if (token.length() > 0) {
         tokens.addElement(token.toString());
     }
     // convert the vector into an array
     String[] splitArray = new String[tokens.size()];
     for (int i=0; i < splitArray.length; i++) {
         splitArray[i] = (String)tokens.elementAt(i);
     }
     return splitArray;
 }
    
    static double powSqrt(double x, double y){
  int den = 1024, num = (int)(y*den), iterations = 10;
  double n = Double.MAX_VALUE;
  
  while( n >= Double.MAX_VALUE && iterations > 1)
  {
   n = x;
   
   for( int i=1; i < num; i++ )n*=x;

   if( n >= Double.MAX_VALUE ) 
   {
    iterations--;
    den = (int)(den / 2);
    num = (int)(y*den);
   }
  } 

  for( int i = 0; i <iterations; i++ )n = Math.sqrt(n);
  
  return n;
 }

    
    static int[] arrAdd(int data,int[] datas){
        int max = datas.length;
        int[] temp = new int[max+1];
        for(int i=0; i<max; i++){
            temp[i]=datas[i];
        }
        temp[max] = data;
        return temp;
    }
    
    static int invers(double c, int p){
        int invc = 0;
        c = c%p;
        int[] a = {1,0,p};
        int[] b = {0,1,(int)c};
        boolean ulang = true;
        while(ulang){
            if(b[2]==0){
                ulang = false;
                break;
            }
            if(b[2]==1){
                invc = b[1]%p;
                ulang = false;
                break;
            }
            if(ulang){
                int q = (int) Math.floor(a[2]/b[2]);
                int[] t= {(a[0]-q*b[0]), a[1]-q*b[1], a[2]-q*b[2]};
                a = b;
                b = t;
            }
        }
        return invc;
    }
    
    static int[] kali(int p, int a, int b, int k, int[] xy){
        
        int n = k%2;
        k = (int)Math.floor(k/2);
        //System.out.println(k);
        int[] R = jumlah(p,a,b,xy[0],xy[1],xy[0],xy[1]);
        System.out.println("["+xy[0]+","+xy[1]+"]+"+"["+xy[0]+","+xy[1]+"]"+"="+"["+R[0]+","+R[1]+"]");
        if(k>1){
            R = kali(p, a, b, k, R);
        }
        if(n==1){
            System.out.print("["+R[0]+","+R[1]+"]");
            R = jumlah(p,a,b,R[0],R[1],xy[0],xy[1]);
            System.out.println("+"+"["+xy[0]+","+xy[1]+"]="+"["+R[0]+","+R[1]+"]");
        }
        return R;
    }
    
    static int[] jumlah(int p, int a, int b, int x1, int y1, int x2, int y2){
        int point[] = new int[2];
        int x3, y3;
        if(x1==0 && y1==0){
            x3 = x2;
            y3 = y2;
        }else if(x2==0 && y2==0){
            x3 = x1;
            y3 = y1;
        }else if(y1 == -y2){
            x3 = 0;
            y3 = 0;
        }else if(x1==x2 && y1==y2){
            double inv = invers(2*y1,p);
            //System.out.println(inv);
            double lambda = (3*powSqrt(x1, 2)+a)*inv;
            lambda = lambda%p;
            
            x3 = (int)powSqrt(lambda, 2) - 2*x1;
            y3 = -y1 + (int)lambda*(x1-x3);
            
            int n=1;
            while(x3<0){
                x3 = n*p+x3;
                n++;
            }
        
            n=1;
            while(y3<0){
                y3 = n*p+y3;
                n++;
            }
           
            point[0] = x3%p;
            point[1] = y3%p;
            //System.out.println(point[0]+","+point[1]);
        }else{
            int tX = (x2-x1);
            int tY = (y2-y1);
            int lambda = tY*(invers(tX,p));
            //System.out.println(invers(tX,p));
            lambda = lambda%p;
            //System.out.println("Lambda : "+lambda);
            x3 = (int)(powSqrt(lambda, 2)-x1-x2);
            y3 = lambda*(x1-x3)-y1;
            int n=1;
            while(x3<0){
                x3 = n*p+x3;
                n++;
            }
        
            n=1;
            while(y3<0){
                y3 = n*p+y3;
                n++;
            }
        
            point[0] = x3%p;
            point[1] = y3%p;
            //System.out.println(point[0]+","+point[1]);
        }
        return point;
    }
    
    static int[][] titik(int p, int a, int b, int x){
        int dmp[][] = new int[0][2];
        if(isCurve(a,b,p)){
            double yKuadrat = ((a*powSqrt(x,3))+x+b)%p;
            for(int i=0; i<p; i++){
                double t = powSqrt(i,2)%p;
                if(yKuadrat==t){
                    //dmp = addArr();
                    System.out.print("("+x+","+i+"), ");
                }
            }
        }else{
            System.out.println("coba nilai a atau b yang lain.");
        }
        return dmp;
    }
    
    public static boolean isCurve(int a, int b, int p){
        double hasil = (4*powSqrt(a, 3))+(27*powSqrt(b, 2));
        int modp  = (int)hasil%p;
        if(hasil==0){
            return false;
        }
        return true;
    }
    
    public static boolean isPrime(int p, int a){
        if(powSqrt(a, p)%p==a){
            return true;
        }
        return false;
    }
}



semoga bermanfaat :)


Written by Hari Santoso
Java ME : Algoritma Kriptografi Elliptic Curve Cryptography (ECC)
Bahasan: Dibawah ini adalah algoritma kriptografi kurva eliptik (ECC) dalam basaha java, khususnya J2ME. Pada kelas tersebut ada fungsi-fungsi yang...
Published at Kamis, 11 Juli 2013, Updated at Kamis, 11 Juli 2013
Reviewed by dr. on
Rating: 4.7

3 komentar :

  1. dari web seluruh indonesia, cuma elangsakti yang membahas ECC dalam bentuk bahasa pemrograman. terima kasih masbro atas postingan beritanya :)

    BalasHapus
  2. boleh gak minta pembahasannya dalam bentuk matematikanya. yeah kalu mua sih hehehehe :D

    BalasHapus
    Balasan
    1. itu kalo dicompile keluar perhitungannya bro..
      Atau sampeyan bisa cek di sini http://www.elangsakti.com/2013/07/perhitungan-algoritma-kriptografi-kurva-eliptik-elliptic-curve-cryptography-ecc.html

      Hapus