Application Center - Maplesoft

# Elliptic Curve Cryptography

You can switch back to the summary page by clicking here.

elliptic_program.mws

Elliptic Curve Cryptography

Pauline Hong

Duke University

pauline.hong@duke.edu

www.duke.edu/~ph6

To see how to use this program, see the example at the end of this worksheet.

To see how this program works, see the accompanying paper.

User routines

 > init_receiver := proc()    local   G,g,h,kappa,n;    global  Privkey,Pubkey;    Privkey := 1309500873854749099831268309457391717722850279;    G := [-3,          2455155546008945908945579827824778998937758030093070285253,          6277101735386680763835789423207666416083908700390324961279];    g := [602046843592854700404561654781648738821600320709046855698,          1580573966983949753944652941399918970627913726427538969730];    h := giop(G,g,Privkey);    kappa := 2^8;    n := floor(evalf((log[2](G[3])-log[2](kappa))/8))-1;    Pubkey := [G,g,h,kappa,n]; end:

 > send_message := proc(T)    local   S,s,C,x,p,c;    S := split(T);    C := [];    for s in S do       x := text_to_num(s);       p := num_to_point(x);       c := encrypt(p);       C := [op(C),c];    od;    return C; end:

 > receive_message := proc(C)    local   T,c,p,x,t;    T := "";    for c in C do       p := decrypt(c);       x := point_to_num(p);       t := num_to_text(x);       T := cat(T,t);    od;    return T; end:

System routines

 > split := proc(T)    local   n,num_parts,pieces,i;    global  Pubkey;    n         := Pubkey[5];    num_parts := floor(length(T)/n);    pieces := [];    for i from 0 to (num_parts-1)*n by n do       pieces := [op(pieces),substring(T,i+1..i+n)];    od;    if (length(T)/n - num_parts) > 0 then       pieces := [op(pieces),substring(T,num_parts*n+1..length(T))];    end;    return pieces; end:

 > text_to_num := proc(t)    local   tb,x,i;    tb := convert(t,'bytes');    x := 0;    for i from length(t) to 1 by -1 do       x := x*2^8 + tb[i];    od;    return x; end:

 > num_to_text := proc(x)    local   n,xb,tb,i,t;    global  Pubkey;    n := Pubkey[5];    xb := x;    tb := [];    for i from 1 to n do       xb := iquo(xb,2^8,'r');       tb := [op(tb),r];    od;    t := convert(tb,'bytes');    return t; end:

 > num_to_point := proc(x)    local   a,b,p,xp,c,yp,G,kappa;    global  Pubkey;    G := Pubkey[1];    a := G[1];    b := G[2];    p := G[3];    kappa := Pubkey[4];    for xp from kappa*x to kappa*(x+1)-1 do       c := xp^3 + a*xp + b mod p;       yp := numtheory[msqrt](c,p);       if yp <> FAIL then          return [xp,yp];       fi;    od;    print("Very unlikely thing happened!!!           You need to increase kappa value.");    return FAIL; end:

 > point_to_num := proc(p)    local   kappa;    global  Pubkey;    kappa := Pubkey[4];    return floor(p[1]/kappa); end:

 > encrypt := proc(p)    local   G,g,h,genrand,s,c1,c2,c;    global  Pubkey;    G := Pubkey[1];    g := Pubkey[2];    h := Pubkey[3];    genrand := rand(2..10);    s  := genrand();    c1 := giop(G,g,s);    c2 := gop(G,giop(G,h,s),p);    c  := [c1,c2];    return c; end:

 > decrypt := proc(c)    local   G;    global  Privkey,Pubkey;    G := Pubkey[1];    return gop(G,giop(G,ginv(G,c[1]),Privkey),c[2]); end:

Group routines

 > giop := proc(G,A,k)    local   kp,Ap,r;    if k = 0 then       return 0;    fi;    kp := iquo(k,2,'r');    Ap := giop(G,A,kp);    if r = 0 then       return gop(G,Ap,Ap);    else       return gop(G,A,gop(G,Ap,Ap));    fi; end:

 > giop_slow := proc(G,A,k)    local   B,i;    B := 0;    for i from 1 to k do       B := gop(G,A,B);    od;    return B; end:

 > gop := proc(G,A,B)    local   a,b,p,xA,yA,xB,yB,xC,yC,C,slope;    a := G[1];    b := G[2];    p := G[3];    if A = 0 then       return B;    fi;    if B = 0 then       return A;    fi;    xA := A[1];    yA := A[2];    xB := B[1];    yB := B[2];    if (xA - xB) mod p = 0 and (yA + yB) mod p = 0 then       return 0;    fi;          if (xA - xB) mod p = 0 and (yA - yB) mod p = 0 then       slope := (3*xA^2 + a) / (2*yA) mod p;    else       slope := (yA - yB) / (xA - xB) mod p;    fi;    xC := slope^2 - xA - xB mod p;    yC := -yA + slope*(xA - xC) mod p;    C := [xC,yC];    return C; end:

 > ginv := proc(G,A)    local   p;    p := G[3];    if A = 0 then       return 0;    fi;    return [A[1],-A[2] mod p]; end:

Examples

 > sent := "The urge to discover secrets is deeply ingrained in human nature; even the least curious mind is roused by the promise of sharing knowledge withheld from others. Some are fortunate enough to find a job which consists of the solution of mysteries, but most of us are driven to sublimate this urge by the solving of artificial puzzles designed for our entertainment. Detective stories or crossword puzzles cater for the majority; the solution of secret codes may be the pursuit of the few. (John Chadwick from The Decipherment of Linear B, as quoted in The Code Book, by Simon Singh)":

 > encrypted := send_message(sent);