Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Cryptography Fundamentals Lab Assignment - 6: ECC and Digital Signature Verification

Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

17BCE0147 VIJAY SURYA

CRYPTOGRAPHY FUNDAMENTALS

LAB ASSIGNMENT - 6

ECC and Digital Signature Verification

Code:

typedef long long int dlong;


double RAND_MAX;
int NULL;
typedef struct {
dlong x, y;
} epnt;

typedef struct {
long a, b;
dlong N;
epnt G;
dlong r;
} curve;

typedef struct {
long a, b;
} pair;

const long mxN = 1073741789;

const long mxr = 1073807325;

const long inf = -2147483647;

curve e;

epnt zerO;

int inverr;

long exgcd (long v, long u)


{
register long q, t;
long r = 0, s = 1;
if (v < 0) v += u;

while (v) {
q = u / v;
17BCE0147 VIJAY SURYA
t = u - q * v;
u = v; v = t;
t = r - q * s;
r = s; s = t;
}
if (u != 1) {
printf (" impossible inverse mod N, gcd = %d\n", u);
inverr = 1;
}
return r;
}

static inline dlong modn (dlong a)


{
a %= e.N;
if (a < 0) a += e.N;
return a;
}

dlong modr (dlong a)


{
a %= e.r;
if (a < 0) a += e.r;
return a;
}

long disc (void)


{
dlong c, a = e.a, b = e.b;
c = 4 * modn(a * modn(a * a));
return modn(-16 * (c + 27 * modn(b * b)));
}

int isO (epnt p)


{
return (p.x == inf) && (p.y == 0);
}

int ison (epnt p)


{
long r, s;
if (! isO (p)) {
r = modn(e.b + p.x * modn(e.a + p.x * p.x));
s = modn(p.y * p.y);
}
return (r == s);
}
17BCE0147 VIJAY SURYA

void padd (epnt *r, epnt p, epnt q)


{
dlong la, t;

if (isO(p)) {*r = q; return;}


if (isO(q)) {*r = p; return;}

if (p.x != q.x) {
t = p.y - q.y;
la = modn(t * exgcd(p.x - q.x, e.N));
}
else
if ((p.y == q.y) && (p.y != 0)) {
t = modn(3 * modn(p.x * p.x) + e.a);
la = modn(t * exgcd (2 * p.y, e.N));
}
else
{*r = zerO; return;}

t = modn(la * la - p.x - q.x);


r->y = modn(la * (p.x - t) - p.y);
r->x = t; if (inverr) *r = zerO;
}

// R:= multiple kP
void pmul (epnt *r, epnt p, long k)
{
epnt s = zerO, q = p;

for (; k; k >>= 1) {
if (k & 1) padd(&s, s, q);
if (inverr) {s = zerO; break;}
padd(&q, q, q);
}
*r = s;
}

void pprint (char *f, epnt p)


{
dlong y = p.y;

if (isO (p))
printf ("%s (0)\n", f);

else {
if (y > e.N - y) y -= e.N;
printf ("%s (%lld, %lld)\n", f, p.x, y);
17BCE0147 VIJAY SURYA
}
}

int ellinit (long i[])


{
long a = i[0], b = i[1];
e.N = i[2]; inverr = 0;

if ((e.N < 5) || (e.N > mxN)) return 0;

e.a = modn(a);
e.b = modn(b);
e.G.x = modn(i[3]);
e.G.y = modn(i[4]);
e.r = i[5];

if ((e.r < 5) || (e.r > mxr)) return 0;

printf ("\nE: y^2 = x^3 + %dx + %d", a, b);


printf (" (mod %lld)\n", e.N);
pprint ("base point G", e.G);
printf ("order(G, E) = %lld\n", e.r);

return 1;
}

double rnd(void)
{
return rand() / ((double)RAND_MAX + 1);
}

pair signature (dlong s, long f)


{
long c, d, u, u1;
pair sg;
epnt V;

printf ("\nsignature computation\n");


do {
do {
u = 1 + (long)(rnd() * (e.r - 1));
pmul (&V, e.G, u);
c = modr(V.x);
}
while (c == 0);

u1 = exgcd (u, e.r);


d = modr(u1 * (f + modr(s * c)));
}
17BCE0147 VIJAY SURYA
while (d == 0);
printf ("one-time u = %d\n", u);
pprint ("V = uG", V);

sg.a = c; sg.b = d;
return sg;
}

int verify (epnt W, long f, pair sg)


{
long c = sg.a, d = sg.b;
long t, c1, h1, h2;
dlong h;
epnt V, V2;

t = (c > 0) && (c < e.r);


t &= (d > 0) && (d < e.r);
if (! t) return 0;

printf ("\nsignature verification\n");


h = exgcd (d, e.r);
h1 = modr(f * h);
h2 = modr(c * h);
printf ("h1,h2 = %d, %d\n", h1,h2);
pmul (&V, e.G, h1);
pmul (&V2, W, h2);
pprint ("h1G", V);
pprint ("h2W", V2);
padd (&V, V, V2);
pprint ("+ =", V);
if (isO (V)) return 0;
c1 = modr(V.x);
printf ("c' = %d\n", c1);

return (c1 == c);


}

void ec_dsa (long f, long d)


{
long i, s, t;
pair sg;
epnt W;

t = (disc() == 0);
t |= isO (e.G);
pmul (&W, e.G, e.r);
t |= ! isO (W);
t |= ! ison (e.G);
if (t) goto errmsg;
17BCE0147 VIJAY SURYA
printf ("\nkey generation\n");
s = 1 + (long)(rnd() * (e.r - 1));
pmul (&W, e.G, s);
printf ("private key s = %d\n", s);
pprint ("public key W = sG", W);

t = e.r;
for (i = 1; i < 32; i <<= 1)
t |= t >> i;
while (f > t) f >>= 1;
printf ("\naligned hash %x\n", f);

sg = signature (s, f);


if (inverr) goto errmsg;
printf ("signature c,d = %d, %d\n", sg.a, sg.b);

if (d > 0) {
while (d > t) d >>= 1;
f ^= d;
printf ("\ncorrupted hash %x\n", f);
}

t = verify (W, f, sg);


if (inverr) goto errmsg;
if (t)
printf ("Valid\n_____\n");
else
printf ("invalid\n_______\n");

return;

errmsg:
printf ("invalid parameter set\n");
printf ("_____________________\n");
}

int main (void)


{
typedef long eparm[6];
long d, f;
zerO.x = inf; zerO.y = 0;
srand(time(NULL));

eparm *sp, sets[10] = {

{355, 671, 1073741789, 13693, 10088, 1073807281},


{ 0, 7, 67096021, 6580, 779, 16769911},
{ -3, 1, 877073, 0, 1, 878159},
{ 0, 14, 22651, 63, 30, 151},
17BCE0147 VIJAY SURYA
{ 3, 2, 5, 2, 1, 5},

{ 0, 7, 67096021, 2402, 6067, 33539822},

{ 0, 7, 67096021, 6580, 779, 67079644},

{ 0, 7, 877069, 3, 97123, 877069},

{ 39, 387, 22651, 95, 27, 22651},


};

f = 0x789abcde; d = 0;

for (sp = sets; ; sp++) {


if (ellinit (*sp))
ec_dsa (f, d);

else
break;
}
}

OUTPUT:

17BCE0147 VIJAY SURYA

ECC :

DUMP = FALSE

DEF FINDMODULARINVERSE(A, MOD):

WHILE(A < 0):

A = A + MOD ;

X1 = 1;

X2 = 0;

X3 = MOD ;

Y1 = 0;

Y2 = 1;

Y3 = A;

Q = INT(X3 / Y3)

T1 = X1 - Q*Y1

T2 = X2 - Q*Y2

T3 = X3 - (Q*Y3)

IF DUMP == TRUE:

PRINT("Q\TX1\TX2\TX3\TY1\TY2\TY3\TT1\TT2\TT3")

PRINT("----------------------------------------------------------------------------")

PRINT(Q,"\T",X1,"\T",X2,"\T",X3,"\T",Y1,"\T",Y2,"\T",Y3,"\T",T1,"\T",T2,"\T",T3)

WHILE(Y3 != 1):

X1 = Y1; X2 = Y2; X3 = Y3

Y1 = T1; Y2 = T2; Y3 = T3

Q = INT(X3 / Y3) T1 = X1 - Q*Y1 T2 = X2 - Q*Y2 T3 = X3 - (Q*Y3)

IF DUMP == TRUE:

PRINT(Q,"\T",X1,"\T",X2,"\T",X3,"\T",Y1,"\T",Y2,"\T",Y3,"\T",T1,"\T",T2,"\T",T3)

PRINT("-----------------------------------------`-----------------------------------")

PRINT("")

WHILE(Y2 < 0):

Y2 = Y2 + MOD

RETURN Y2

DEF POINTADDITION(X1, Y1, X2, Y2, A, B, MOD):

IF X1 == X2 AND Y1 == Y2: #DOUBLING

BETA = (3*X1*X1 + A) * (FINDMODULARINVERSE(2*Y1, MOD))

ELSE:

#POINT ADDITION

BETA = (Y2 - Y1)*(FINDMODULARINVERSE((X2 - X1), MOD))

X3 = BETA*BETA - X1 - X2 Y3 = BETA*(X1 - X3) - Y1

X3 = X3 % MOD Y3 = Y3 % MOD

WHILE(X3 < 0):

X3 = X3 + MOD

WHILE(Y3 < 0):

Y3 = Y3 + MOD

RETURN X3, Y3

DEF APPLYDOUBLEANDADDMETHOD(X0, Y0, K, A, B, MOD): X_TEMP = X0):

X_TEMP = X0

Y_TEMP = Y0

KASBINARY = BIN(K) #0B1111111001

KASBINARY = KASBINARY[2:LEN(KASBINARY)] #1111111001 #PRINT(KASBINARY)

FOR I IN RANGE(1, LEN(KASBINARY)):

CURRENTBIT = KASBINARY[I: I+1]

#ALWAYS APPLY DOUBLING

X_TEMP, Y_TEMP = POINTADDITION(X_TEMP, Y_TEMP, X_TEMP, Y_TEMP, A, B, MOD)

IF CURRENTBIT == '1':

#ADD BASE POINT

X_TEMP, Y_TEMP = POINTADDITION(X_TEMP, Y_TEMP, X0, Y0, A, B, MOD)

RETURN X_TEMP, Y_TEMP

17BCE0147 VIJAY SURYA


APPLYBRUTEFORCE = TRUE

APPLYKEYEXCHANGE = TRUE

APPLYDIGITALSIGNATURE = TRUE

APPLYSYMMETRICENCRYPTION = TRUE

APPLYORDEROFGROUP = FALSE

APPLYECDLP = FALSE

NABLEBITCOINPARAMS = TRUE

#------------------------------------ #CURVE CONFIGURATION

IF ENABLEBITCOINPARAMS == TRUE:

MOD = POW(2, 256) - POW(2, 32) - POW(2, 9) - POW(2, 8) - POW(2, 7) - POW(2, 6) - POW(2, 4) - POW(2,
0)

ORDER =
115792089237316195423570985008687907852837564279074904382605163141518161494337

ELSE:

MOD = 199 #F199

ORDER = 211 #ORDER OF GROUP - NUMBER OF POINTS ON THE CURVE

#CURVE CONFIGURATION

# Y^2 = X^3 + A*X + B = Y^2 = X^3 + 7

A=0

B=7

#BASE POINT ON THE CURVE

IF ENABLEBITCOINPARAMS == TRUE:

X0 = 55066263022277343669578718895168534326250603453777594175500187360389116729240 Y0
= 32670510020758816978083085130507043184471273380659243275938904335757337482424

ELSE:

X0 = 2

Y0 = 24

PRINT("---------------------")

PRINT("INITIAL CONFIGURATION")

PRINT("---------------------")

PRINT("CURVE: Y^2 = X^3 + ",A,"*X + ",B, " MOD ", MOD," , #F(",MOD,") = ", ORDER) PRINT("BASE
POINT: (",X0,", ",Y0,")")

#PRINT("MODULO: ", MOD) #PRINT("ORDER OF GROUP: ", ORDER) PRINT()


#------------------------------------

#------------------------------------ #BRUTE FORCE

IF APPLYBRUTEFORCE == TRUE:

PRINT("\N-----------------------------------------") PRINT("BRUTE FORCE")


PRINT("-----------------------------------------")

PRINT("P: (", X0,", ",Y0,")")

NEW_X, NEW_Y = POINTADDITION(X0, Y0, X0, Y0, A, B, MOD) PRINT("2 P: (",NEW_X,", ",NEW_Y,")")

FOR I IN RANGE(3, 2000+1):

TRY:

NEW_X, NEW_Y = POINTADDITION(NEW_X, NEW_Y, X0, Y0, A, B, MOD)

PRINT(I,"P: (",NEW_X,", ",NEW_Y,")")

EXCEPT:

PRINT("ORDER OF GROUP: ",I)

BREAK

#------------------------------------ #KEY EXCHANGE

IF APPLYKEYEXCHANGE == TRUE:

PRINT("\N------------------------------------------") PRINT("ELLIPTIC CURVE DIFFIE HELLMAN KEY


EXCHANGE") PRINT("------------------------------------------")

ALICEPRIVATE = 2010000000000017

ALICEPUBLICX, ALICEPUBLICY = APPLYDOUBLEANDADDMETHOD(X0, Y0, ALICEPRIVATE, A, B,


MOD) PRINT("ALICE PUBLIC KEY: (",ALICEPUBLICX,", ", ALICEPUBLICY,")")

BOBPRIVATE = 2010000000000061

BOBPUBLICX, BOBPUBLICY = APPLYDOUBLEANDADDMETHOD(X0, Y0, BOBPRIVATE, A, B, MOD)


PRINT("BOB PUBLIC KEY: (",BOBPUBLICX,", ", BOBPUBLICY,")")

PRINT("")

ALICESHAREDX, ALICESHAREDY = APPLYDOUBLEANDADDMETHOD(BOBPUBLICX, BOBPUBLICY,


ALICEPRIVATE, A, B, MOD) PRINT("ALICE SHARED KEY: (",ALICESHAREDX,", ", ALICESHAREDY,")")

17BCE0147 VIJAY SURYA


BOBSHAREDX, BOBSHAREDY = APPLYDOUBLEANDADDMETHOD(ALICEPUBLICX, ALICEPUBLICY,
BOBPRIVATE, A, B, MOD) PRINT("BOB SHARED KEY: (",BOBSHAREDX,", ", BOBSHAREDY,")")

#------------------------------------

#DIGITAL SIGNATURE

IF APPLYDIGITALSIGNATURE == TRUE:

PRINT("\N------------------------------------------") PRINT("ELLIPTIC CURVE DIGITAL SIGNATURE


ALGORITHM") PRINT("------------------------------------------")

MESSAGE = B"ECC BEATS RSA" IMPORT HASHLIB

HASHHEX = HASHLIB.SHA1(MESSAGE).HEXDIGEST() HASH = INT(HASHHEX, 16)

PRINT("MESSAGE: ", MESSAGE) PRINT("HASH: ", HASH)

PRIVATEKEY =
75263518707598184987916378021939673586055614731957507592904438851787542395619
PUBLICKEYX, PUBLICKEYY = APPLYDOUBLEANDADDMETHOD(X0, Y0, PRIVATEKEY, A, B, MOD)

PRINT("PUBLIC KEY: ",PUBLICKEYX, ", ", PUBLICKEYY)

RANDOMKEY =
28695618543805844332113829720373285210420739438570883203839696518176414791234 """IMPORT
RANDOM

RANDOMKEY = RANDOM.GETRANDBITS(128)"""

#PRINT("RANDOM KEY: ", RANDOMKEY)

RANDOMPOINTX, RANDOMPOINTY = APPLYDOUBLEANDADDMETHOD(X0, Y0, RANDOMKEY, A, B,


MOD) PRINT("RANDOM POINT: (", RANDOMPOINTX,", ",RANDOMPOINTY)

#SIGNING

R = RANDOMPOINTX % ORDER

S = HASH + (R * PRIVATEKEY)

S = S * FINDMODULARINVERSE(RANDOMKEY, ORDER) S = S % ORDER

PRINT("SIGNATURE") PRINT("R: ", R) PRINT("S: ", S)

#VERIFICATION PRINT("\NVERIFICATION...")

W = FINDMODULARINVERSE(S, ORDER)

U1 = APPLYDOUBLEANDADDMETHOD(X0, Y0, (HASH * W) % ORDER, A, B, MOD)

U2 = APPLYDOUBLEANDADDMETHOD(PUBLICKEYX, PUBLICKEYY, (R * W) % ORDER, A, B, MOD)

CHECKPOINTX, CHECKPOINTY = POINTADDITION(U1[0], U1[1], U2[0], U2[1], A, B, MOD)


PRINT("CHECKPOINT: (",CHECKPOINTX,", ",CHECKPOINTY,")")

PRINT() PRINT("(CHECKPOINT)X ? = R") PRINT(CHECKPOINTX," ?= ", R) PRINT()

IF(CHECKPOINTX == R):

PRINT("SIGNATURE IS VALID...")

ELSE:

PRINT("INVALID SIGNATURE DETECTED!!!")

#SYMMETRIC ENCRYPTION

IF APPLYSYMMETRICENCRYPTION == TRUE:

PRINT("\N------------------------------------------") PRINT("ELLIPTIC CURVE ELGAMAL


CRYPTOSYSTEM") PRINT("------------------------------------------")

#1000P

PLAINTEXTX =
33614996735103061868086131503312627786077049888376966084542785773152043381677
PLAINTEXTY =
84557594361191031609962062080128931200952163654712344162477769532776951195137

PRINT("PLAINTEXT: (",PLAINTEXTX,", ",PLAINTEXTY,")")

SECRETKEY =
75263518707598184987916378021939673586055614731957507592904438851787542395619
PUBLICKEYX, PUBLICKEYY = APPLYDOUBLEANDADDMETHOD(X0, Y0, SECRETKEY, A, B, MOD)

PRINT("PUBLIC KEY: (",PUBLICKEYX, ", ", PUBLICKEYY,")")

#ENCRYPTION

RANDOMKEY =
28695618543805844332113829720373285210420739438570883203839696518176414791234 """IMPORT
RANDOM

RANDOMKEY = RANDOM.GETRANDBITS(128)"""

C1X, C1Y = APPLYDOUBLEANDADDMETHOD(X0, Y0, RANDOMKEY, A, B, MOD)

C2X, C2Y = APPLYDOUBLEANDADDMETHOD(PUBLICKEYX, PUBLICKEYY, RANDOMKEY, A, B, MOD)


C2X, C2Y = POINTADDITION(C2X, C2Y, PLAINTEXTX, PLAINTEXTY, A, B, MOD)

17BCE0147 VIJAY SURYA


PRINT("CIPHERTEXT") PRINT("C1: (", C1X,", ",C1Y,")") PRINT("C2: (", C2X,", ",C2Y,")") PRINT("")

#DECRYPTION

#MESSAGE = C2 - SECRETKEY * C1

DX, DY = APPLYDOUBLEANDADDMETHOD(C1X, C1Y, SECRETKEY, A, B, MOD)

DY = DY * -1 #CURVE IS SYMMETRIC ABOUT X-AXIS. IN THIS WAY, INVERSE POINT FOUND

#PRINT("D: (",DX,", ",DY,")")

DECRYPTED = POINTADDITION(C2X, C2Y, DX, DY, A, B, MOD) PRINT("DECRYPTED: ",DECRYPTED,"")

IF APPLYORDEROFGROUP == TRUE:

PRINT("\N------------------------------------------")

PRINT("FIND ORDER OF ELLIPTIC CURVE GROUP")

PRINT("------------------------------------------")

FROM MATH IMPORT SQRT

Q = APPLYDOUBLEANDADDMETHOD(X0, Y0, MOD + 1, A, B, MOD) PRINT("(MOD + 1)P = ", MOD +


1,"P = ",Q)

M = INT(SQRT(SQRT(MOD))) + 1

PRINT("1 + (MOD^1/4) = 1 + (",MOD,")^1/4 = ",M) PRINT()

TERMINATE = FALSE

FOR J IN RANGE (1, M+1):

JP = APPLYDOUBLEANDADDMETHOD(X0, Y0, J, A, B, MOD)

PRINT(J,"P = ",JP, " -> ", END="")

FOR K IN RANGE (-M, M+1):

CHECKPOINT = APPLYDOUBLEANDADDMETHOD(X0, Y0, M*2*K, A, B, MOD)

CHECKPOINT = POINTADDITION(CHECKPOINT[0], CHECKPOINT[1], Q[0], Q[1], A, B, MOD)

PRINT(CHECKPOINT," ", END="")

IF CHECKPOINT[0] == JP[0]: #CHECK X-CORRDINATES OF CHECKPOINT AND JP

ORDEROFGROUP = MOD + 1 + M*2*K

PRINT("\NORDER OF GROUP SHOULD BE ", ORDEROFGROUP ," ± ", J)

TRY:

APPLYDOUBLEANDADDMETHOD(X0, Y0, ORDEROFGROUP + J, A, B, MOD)

EXCEPT:

ORDEROFGROUP = ORDEROFGROUP + J

TERMINATE = TRUE

BREAK

TRY:

APPLYDOUBLEANDADDMETHOD(X0, Y0, ORDEROFGROUP - J, A, B, MOD)

EXCEPT:

ORDEROFGROUP = ORDEROFGROUP - J

TERMINATE = TRUE

BREAK

PRINT()

IF TERMINATE == TRUE:

BREAK

PRINT("ORDER OF GROUP: ", ORDEROFGROUP)

IF APPLYECDLP == TRUE:

PRINT("\N------------------------------------------")

PRINT("FIND K SUCH THAT Q = K X P")

PRINT("------------------------------------------")

FROM MATH IMPORT SQRT

K = 177

PUBLICKEY = APPLYDOUBLEANDADDMETHOD(X0, Y0, K, A, B, MOD) PRINT("PUBLIC KEY: ",


PUBLICKEY)

PRINT("FIND K SUCH THAT ",PUBLICKEY," = K X (",X0,", ",Y0,")")

TERMINATE = FALSE STEP = 0

#------------------------

M = INT(SQRT(ORDER)) + 1

FOR I IN RANGE(1, M):

IP = APPLYDOUBLEANDADDMETHOD(X0, Y0, I, A, B, MOD) #PRINT("LOOK FOR", IP," IN THE


FOLLOWING SERIES ")

FOR J IN RANGE(1, M):

17BCE0147 VIJAY SURYA


CHECKPOINT = APPLYDOUBLEANDADDMETHOD(X0, Y0, J*M, A, B, MOD)

CHECKPOINT = POINTADDITION(PUBLICKEY[0], PUBLICKEY[1], CHECKPOINT[0],


-CHECKPOINT[1], A, B, MOD) #PRINT(CHECKPOINT, " ",END ="")

#IF IP[0] == CHECKPOINT[0] AND IP[1] == CHECKPOINT[1]:

IF IP == CHECKPOINT:

PRINT(I+J*M," MOD ",ORDER)

PRINT("ECDLP SOLVED IN", I+M,"TH STEP")

TERMINATE = TRUE

BREAK

IF TERMINATE == TRUE:

BREAK

OUTPUT:
17BCE0147 VIJAY SURYA

You might also like