├── manual.docx
├── manual.pdf
├── examples
├── FiniteFieldArithmeticI
├── pohlig_2_1_I
├── pohligI
├── ELGAMAL_EncryptionI
├── ECDSAI
├── ECarithmeticI
├── ELGAMAL_DSAI
├── pohlig.sh
├── ECDSA.sh
├── ECarithmetic.sh
├── ELGAMAL_DSA.sh
├── FiniteFieldArithmetic.sh
├── ELGAMAL_Encryption.sh
├── ECarithmetic_2_1_I
├── pohlig_2_2_I
├── command.sh
├── ECDSA.cpp
├── ELGAMAL_Encryption.cpp
├── ELGAMAL_DSA.cpp
├── pohlig.cpp
├── ECarithmetic_2_2_I
├── ECarithmetic.cpp
└── FiniteFieldArithmetic.cpp
├── README.md
├── src
├── compile.sh
├── attacksECC.h
├── ellipticCurve.h
├── ECC.h
├── ECC.cpp
├── attacksECC.cpp
└── ellipticCurve.cpp
└── assets
├── givpoly1.h
└── givpoly1io.inl
/manual.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/poojagarg/ECC/HEAD/manual.docx
--------------------------------------------------------------------------------
/manual.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/poojagarg/ECC/HEAD/manual.pdf
--------------------------------------------------------------------------------
/examples/FiniteFieldArithmeticI:
--------------------------------------------------------------------------------
1 | 7
2 | 2
3 | 2
4 | 1
5 | 6
6 | 3
7 | 0
8 | 4
9 | 1
10 | 2
11 | 6
12 | 11
13 |
14 | Prime p: 7
15 | positive integer m: 2
16 | if(m>1), irreducible polynomial of deg m: X^2+6*X+3
17 | element A- degree of A, followed by co-efficients: 4
18 | element B- degree of B, followed by co-efficients: 2*X+6
19 | Integer n(for scalar multiplication): 11
20 |
--------------------------------------------------------------------------------
/examples/pohlig_2_1_I:
--------------------------------------------------------------------------------
1 | 2
2 | 4
3 | 4
4 | 1
5 | 0
6 | 0
7 | 1
8 | 1
9 | 3
10 | 1
11 | 0
12 | 0
13 | 0
14 | 3
15 | 1
16 | 0
17 | 0
18 | 1
19 | 1
20 | 1
21 | 1
22 | 1
23 | 0
24 | 3
25 | 1
26 | 1
27 | 1
28 | 1
29 | 3
30 | 1
31 | 1
32 | 1
33 | 1
34 | 3
35 | 1
36 | 0
37 | 1
38 | 1
39 | 22
40 |
41 | Prime p
42 | m
43 | if(m>1), give irreducible polynomial
44 | A
45 | B
46 | type of curve- 1
47 | degree d, Fp^(m*d)
48 | (x1,y1)=P
49 | (x2,y2)=Q
50 | n=Ord(P)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Elliptic Curve Cryptography
2 | Implementation in C++
3 |
4 | Please refer to manual.pdf to use this implementation.
5 |
6 | This project implements the following-
7 | 1- Finite Field Arithmetic (of characteristic of Arbitrary precision)
8 | 2- Elliptic Curve Arithmetic
9 | 3- Attacks- Pollard Rho, Pohlig Hellman
10 | 4- Elliptic Curve Cryptosystems- Diffie-Hellman Key Exchange, Digital Signature Schemes (ECDSA, ELGAMAL), Public Key Encryption (ELGAMAL)
11 |
--------------------------------------------------------------------------------
/examples/pohligI:
--------------------------------------------------------------------------------
1 | 7919
2 | 1
3 | 0
4 | 1001
5 | 0
6 | 75
7 | 0
8 | 1
9 | 0
10 | 4023
11 | 0
12 | 6036
13 | 0
14 | 4135
15 | 0
16 | 3169
17 | 7889
18 |
19 | Input 1
20 | _______
21 |
22 | 599
23 | 1
24 | 0
25 | 0
26 | 0
27 | 1
28 | 0
29 | 1
30 | 0
31 | 60
32 | 0
33 | 19
34 | 0
35 | 277
36 | 0
37 | 239
38 | 600
39 |
40 | Input 2
41 | _________
42 |
43 | Prime p
44 | m
45 | if(m>1), give irreducible polynomial
46 | A
47 | B
48 | type of curve= 0
49 | degree d= 1 so E(Fp^(m*d))
50 | (x1,y1)=P
51 | (x2,y2)=Q
52 | n=Ord(P)
--------------------------------------------------------------------------------
/examples/ELGAMAL_EncryptionI:
--------------------------------------------------------------------------------
1 | 7
2 | 2
3 | 2
4 | 1
5 | 6
6 | 3
7 | 1
8 | 2
9 | 3
10 | 1
11 | 5
12 | 4
13 | 0
14 | 1
15 | 0
16 | 2
17 | 1
18 | 2
19 | 3
20 | 1
21 | 3
22 | 5
23 | 1
24 | 6
25 | 2
26 | 59
27 |
28 |
29 | Prime p: 7
30 | positive integer m: 2
31 | if(m>1), irreducible polynomial of deg m: X^2+6*X+3
32 | element A- degree of A, followed by co-efficients: 2*X+3
33 | element B- degree of B, followed by co-efficients: 5*X+4
34 | type 0
35 | degree d: 1
36 | Base Point (x,y) (2,2*x+3)
37 | Message Point (x,y) (6*x+3,6*x+2)
38 | Integer n=Order(P): 59
39 |
40 |
--------------------------------------------------------------------------------
/examples/ECDSAI:
--------------------------------------------------------------------------------
1 | 7
2 | 2
3 | 2
4 | 1
5 | 6
6 | 3
7 | 1
8 | 2
9 | 3
10 | 1
11 | 5
12 | 4
13 | 0
14 | 1
15 | 0
16 | 2
17 | 1
18 | 2
19 | 3
20 | 59
21 | 41
22 | 28
23 | 4
24 |
25 | Prime p: 7
26 | positive integer m: 2
27 | if(m>1), irreducible polynomial of deg m: X^2+6*X+3
28 | element A- degree of A, followed by co-efficients: 2*X+3
29 | element B- degree of B, followed by co-efficients: 5*X+4
30 | type 0
31 | degree d: 1
32 | Base Point (x,y) (2,2*x+3)
33 | Integer n=Order(P): 59
34 | Integer Message m, m1), irreducible polynomial of deg m: X^2+6*X+3
32 | element A- degree of A, followed by co-efficients: 2*X+3
33 | element B- degree of B, followed by co-efficients: 5*X+4
34 | type 0
35 | degree d: 1
36 | P (x1,y1): (2,2*X+3)
37 | Q (x2,y2): (1,6)
38 | T (x3,y3): (1,7) //not a point, you may check that (6*X+3,6*X+2) is a point
--------------------------------------------------------------------------------
/examples/ELGAMAL_DSAI:
--------------------------------------------------------------------------------
1 | 7
2 | 2
3 | 2
4 | 1
5 | 6
6 | 3
7 | 1
8 | 2
9 | 3
10 | 1
11 | 5
12 | 4
13 | 0
14 | 1
15 | 0
16 | 2
17 | 1
18 | 2
19 | 3
20 | 59
21 | 41
22 | 17
23 | 0
24 | 4
25 | 1
26 | 4
27 | 4
28 |
29 | Prime p: 7
30 | positive integer m: 2
31 | if(m>1), irreducible polynomial of deg m: X^2+6*X+3
32 | element A- degree of A, followed by co-efficients: 2*X+3
33 | element B- degree of B, followed by co-efficients: 5*X+4
34 | type 0
35 | degree d: 1
36 | Base Point (x,y) (2,2*x+3)
37 | Integer n=Order(P): 59
38 | Integer Message m, m1), irreducible polynomial of deg m: x^4+x+1
48 | element A- degree of A, followed by co-efficients: x^3
49 | element B- degree of B, followed by co-efficients: x^3 + 1
50 | type 1, so no input for C
51 | degree d: 1
52 | P (x1,y1): (0010, 1111) which is (x,x^3+x^2+x+1)
53 | Q (x2,y2): (1100, 1100)
54 | T (x3,y3): (0001, 0010) //It is not a point, you may check that (0001, 0001) is a point
--------------------------------------------------------------------------------
/examples/pohlig_2_2_I:
--------------------------------------------------------------------------------
1 | 2
2 | 7
3 | 7
4 | 1
5 | 0
6 | 0
7 | 0
8 | 0
9 | 0
10 | 1
11 | 1
12 | 5
13 | 1
14 | 0
15 | 0
16 | 0
17 | 1
18 | 0
19 | 5
20 | 1
21 | 0
22 | 0
23 | 0
24 | 1
25 | 1
26 | 2
27 | 2
28 | 1
29 | 0
30 | 1
31 | 1
32 | 2
33 | 1
34 | 0
35 | 0
36 | 3
37 | 1
38 | 1
39 | 0
40 | 1
41 | 5
42 | 1
43 | 1
44 | 1
45 | 1
46 | 0
47 | 1
48 | 5
49 | 1
50 | 0
51 | 1
52 | 0
53 | 0
54 | 1
55 | 145
56 |
57 | Prime p: 2
58 | positive integer m: 7
59 | if(m>1), irreducible polynomial of deg m: x^7+x+1
60 | element A- degree of A, followed by co-efficients: x^5+x
61 | element B- degree of B, followed by co-efficients: x^5+ x + 1
62 | type of curve- 2
63 | element C- degree of B, followed by co-efficients: x^2 + 1
64 | degree d: 1
65 | P (x1,y1): (100,1101) which is (x^2,x^3+x^2+1)
66 | Q (x2,y2): (111101, 101001)
67 | order(P)=145
--------------------------------------------------------------------------------
/examples/command.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #Run the following commands in the terminal with current directory as "examples"
3 |
4 | chmod +x *.sh
5 |
6 | ./FiniteFieldArithmetic.sh
7 | ./FiniteFieldArithmetic < FiniteFieldArithmeticI
8 |
9 | ./ECarithmetic.sh
10 | ./ECarithmetic < ECarithmeticI
11 | ./ECarithmetic < ECarithmetic_2_1_I
12 | ./ECarithmetic < ECarithmetic_2_2_I
13 |
14 | ./pohlig.sh
15 | ./pohlig < pohligI
16 | ./pohlig < pohlig_2_1_I
17 | ./pohlig < pohlig_2_2_I
18 |
19 | ./ELGAMAL_DSA.sh
20 | ./ELGAMAL_DSA < ELGAMAL_DSAI
21 |
22 | ./ECDSA.sh
23 | ./ECDSA < ECDSAI
24 |
25 | ./ELGAMAL_Encryption.sh
26 | ./ELGAMAL_Encryption < ELGAMAL_EncryptionI
27 |
28 | #To check examples program for Elliptic Curve of type 1 and type 2, we use input file that ends with _2_1_I and _2_2_I for type 1 and type 2 respectively.
29 |
30 |
--------------------------------------------------------------------------------
/examples/ECDSA.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/ECC.h"
2 |
3 | using namespace Givaro;
4 | using namespace std;
5 |
6 | int main()
7 | {
8 | SignatureECDSA S;
9 | Key K;
10 | ellipticCurveFq E_Fq;//define Elliptic Curve over Fq
11 | ExtensionField::Element x,y;
12 | std::cout<<"give (x,y) of Base Point: ";
13 | E_Fq.field->readElement(x);
14 | E_Fq.field->readElement(y);
15 | ecPoint basePoint(x,y);
16 | Integer n,message;
17 | cin>>n;
18 | cin>>message;
19 |
20 | KeyPairGeneration(K, basePoint,E_Fq,n);//ord(P)=n, generates (Q,d such that Q=d*P)
21 | SignatureGeneration(S, K,message,basePoint,E_Fq,n);
22 | showSignature(S);
23 | inputSignature(S);
24 |
25 | if(SignatureVerification(S,message,basePoint,K.Q,E_Fq,n))
26 | {
27 | cout<<"Signature is valid";
28 | }
29 | else
30 | {
31 | cout<<"Signature is invalid";
32 | }
33 |
34 | return 0;
35 | }
--------------------------------------------------------------------------------
/examples/ELGAMAL_Encryption.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/ECC.h"
2 |
3 | using namespace Givaro;
4 | using namespace std;
5 |
6 | int main()
7 | {
8 |
9 | ecPoint M1, M2;
10 | Key K;
11 | ellipticCurveFq E_Fq;//define Elliptic Curve over Fq
12 | ExtensionField::Element x,y;
13 | std::cout<<"give (x,y) of Base Point: ";
14 | E_Fq.field->readElement(x);
15 | E_Fq.field->readElement(y);
16 | ecPoint basePoint(x,y);
17 | std::cout<<"give (x,y) of Message: ";
18 | E_Fq.field->readElement(x);
19 | E_Fq.field->readElement(y);
20 | ecPoint message(x,y);
21 | Integer n;
22 | cin>>n;
23 | KeyPairGeneration(K, basePoint,E_Fq,n);//ord(basePoint)=n, generates (Q,d such that Q=d*basePoint)
24 | EncryptionELGAMAL(M1,M2,basePoint,K.Q,E_Fq,n,message);
25 | DecryptionELGAMAL(message,K.d,basePoint,K.Q,E_Fq,n,M1,M2);
26 | E_Fq.show(message);
27 | return 0;
28 | }
--------------------------------------------------------------------------------
/examples/ELGAMAL_DSA.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/ECC.h"
2 |
3 | using namespace Givaro;
4 | using namespace std;
5 |
6 | int main()
7 | {
8 | SignatureELGAMAL S;
9 | Key K;
10 | ellipticCurveFq E_Fq;//define Elliptic Curve over Fq
11 | ExtensionField::Element x,y;
12 | std::cout<<"give (x,y) of Base Point: ";
13 | E_Fq.field->readElement(x);
14 | E_Fq.field->readElement(y);
15 | ecPoint basePoint(x,y);
16 | Integer n,message;
17 | cin>>n;
18 | cin>>message;
19 |
20 | KeyPairGeneration(K, basePoint,E_Fq,n);//ord(P)=n, generates (Q,d such that Q=d*P)
21 | SignatureGeneration(S, K,message,basePoint,E_Fq,n);
22 | showSignature(S,E_Fq);
23 | inputSignature(S,E_Fq);
24 | if(SignatureVerification(S,message,basePoint,K.Q,E_Fq,n))
25 | {
26 | cout<<"Signature is valid";
27 | }
28 | else
29 | {
30 | cout<<"Signature is invalid";
31 | }
32 | return 0;
33 | }
--------------------------------------------------------------------------------
/examples/pohlig.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/attacksECC.h"
2 |
3 | using namespace std;
4 |
5 | int main()
6 | {
7 | //takes input parameter for E(Fq), where E is elliptic curve defined over K and Fq is extension of K
8 | ellipticCurveFq E_Fq;
9 | E_Fq.show();
10 | Integer n,result;
11 | ExtensionField::Element x1,y1,x2,y2,x3,y3;
12 | std::cout<<"Write x1";
13 | E_Fq.field->readElement(x1);
14 | std::cout<<"Write y1";
15 | E_Fq.field->readElement(y1);
16 | std::cout<<"Write x2";
17 | E_Fq.field->readElement(x2);
18 | std::cout<<"Write y2";
19 | E_Fq.field->readElement(y2);
20 | ecPoint P(x1,y1);
21 | ecPoint Q(x2,y2);
22 | E_Fq.show(P);
23 | E_Fq.show(Q);
24 | std::cout<<"order of P?";
25 | std::cin>>n;
26 | pohligHellman(result, P, Q,n,E_Fq);
27 | //if n is prime, can also use Pollard Rho method- pollardRho(result, P, Q,n,E_Fq);
28 |
29 | return 0;
30 | }
--------------------------------------------------------------------------------
/examples/ECarithmetic_2_2_I:
--------------------------------------------------------------------------------
1 | 2
2 | 7
3 | 7
4 | 1
5 | 0
6 | 0
7 | 0
8 | 0
9 | 0
10 | 1
11 | 1
12 | 2
13 | 1
14 | 1
15 | 0
16 | 5
17 | 1
18 | 0
19 | 0
20 | 0
21 | 1
22 | 1
23 | 2
24 | 1
25 | 1
26 | 1
27 | 1
28 | 5
29 | 1
30 | 0
31 | 0
32 | 0
33 | 1
34 | 1
35 | 5
36 | 1
37 | 0
38 | 0
39 | 1
40 | 0
41 | 0
42 | 5
43 | 1
44 | 0
45 | 1
46 | 1
47 | 0
48 | 0
49 | 5
50 | 1
51 | 1
52 | 1
53 | 0
54 | 1
55 | 0
56 | 3
57 | 1
58 | 0
59 | 1
60 | 1
61 | 6
62 | 1
63 | 1
64 | 1
65 | 0
66 | 1
67 | 1
68 | 1
69 |
70 | Prime p: 2
71 | positive integer m: 7
72 | if(m>1), irreducible polynomial of deg m: x^7+x+1
73 | element A- degree of A, followed by co-efficients: x^2+x
74 | element B- degree of B, followed by co-efficients: x^5+ x + 1
75 | type 2
76 | element C- degree of C, followed by co-efficients: x + 1
77 | degree d: 1
78 | P (x1,y1): (0100011, 0100100) which is (x^5+x+1, x^5+x^2)
79 | Q (x2,y2): (0101100, 0111010)
80 | T (x3,y3): (0001011, 1110111) //It is a point
--------------------------------------------------------------------------------
/src/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | HOME=Users/poojagarg/Downloads/c_library/givaro-3.8.0
3 | g++ -w -DHAVE_CONFIG_H -I. -I/$HOME -I/$HOME -I/$HOME/src/kernel/system -I/$HOME/src/kernel/memory -I/$HOME/src/kernel/zpz -I/$HOME/src/kernel/integer -I/$HOME/src/kernel -I/$HOME/src/library/poly1 -I/$HOME/src/kernel/bstruct -I/$HOME/src/library/tools -O2 -Wall -g -DNDEBUG -UGIVARO_DEBUG -UDEBUG -std=gnu++11 -c -o ellipticCurve.o ellipticCurve.cpp
4 | g++ -w -DHAVE_CONFIG_H -I. -I/$HOME -I/$HOME -I/$HOME/src/kernel/system -I/$HOME/src/kernel/memory -I/$HOME/src/kernel/zpz -I/$HOME/src/kernel/integer -I/$HOME/src/kernel -I/$HOME/src/library/poly1 -I/$HOME/src/kernel/bstruct -I/$HOME/src/library/tools -O2 -Wall -g -DNDEBUG -UGIVARO_DEBUG -UDEBUG -std=gnu++11 -c -o ECC.o ECC.cpp
5 | g++ -w -DHAVE_CONFIG_H -I. -I/$HOME -I/$HOME -I/$HOME/src/kernel/system -I/$HOME/src/kernel/memory -I/$HOME/src/kernel/zpz -I/$HOME/src/kernel/integer -I/$HOME/src/kernel -I/$HOME/src/library/poly1 -I/$HOME/src/kernel/bstruct -I/$HOME/src/library/tools -O2 -Wall -g -DNDEBUG -UGIVARO_DEBUG -UDEBUG -std=gnu++11 -c -o attacksECC.o attacksECC.cpp
6 |
7 |
--------------------------------------------------------------------------------
/src/attacksECC.h:
--------------------------------------------------------------------------------
1 | #ifndef EC_H
2 | #define EC_H
3 | #include "ellipticCurve.h"
4 | #endif
5 |
6 | #ifndef EC_GIVAROINTEGER_H
7 | #define EC_GIVAROINTEGER_H
8 | #include "gmp++/gmp++.h"
9 | #include
10 | #include
11 | #include
12 | #endif
13 |
14 | using namespace Givaro;
15 |
16 | /*computes result such that Q=result*P.
17 | Assumption n is prime, n=order(P) in E(Fq) represented by E_Fq, L is number of partition functions*/
18 | void pollardRho(Integer& result, ecPoint& P, ecPoint& Q,Integer n,ellipticCurveFq& E_Fq,int L);
19 | /*computes result such that Q=result*P.
20 | n=order(P) in E(Fq) represented by E_Fq.
21 | It uses function pollardRho to compute each smaller instance of ECDLP*/
22 | void pohligHellman(Integer& result, ecPoint& P, ecPoint& Q,Integer n,ellipticCurveFq& E_Fq);
23 |
24 | /*Auxillary Functions*/
25 |
26 | /*result=H(input) where 0=& a,std::vector& p);
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/examples/ECarithmetic.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/ellipticCurve.h"
2 |
3 | using namespace Givaro;
4 | using namespace std;
5 |
6 | int main()
7 | {
8 | ellipticCurveFq E_Fq;
9 | E_Fq.show();
10 | ExtensionField::Element x1,y1,x2,y2,x3,y3;
11 | cout<<"Write x1: ";
12 | E_Fq.field->readElement(x1,true);
13 | cout<<"Write y1: ";
14 | E_Fq.field->readElement(y1,true);
15 | cout<<"Write x2: ";
16 | E_Fq.field->readElement(x2,true);
17 | cout<<"Write y2: ";
18 | E_Fq.field->readElement(y2,true);
19 | ecPoint P(x1,y1);
20 | ecPoint Q(x2,y2);
21 | ecPoint R;
22 | E_Fq.Double(R,P);//R=2*P
23 | cout<readElement(x3, true);
31 | E_Fq.field->readElement(y3, true);
32 | ecPoint T(x3,y3);
33 | if(E_Fq.verifyPoint(T))
34 | {
35 | cout<<"T is a point.";
36 | }
37 | else
38 | {
39 | cout<<"T is not a point.";
40 | }
41 | cout<:
29 | // --
30 | // ==========================================================================
31 | template class Poly1Dom;
32 |
33 | template class Poly1Dom;
34 | template class Poly1Dom;
35 |
36 | } // Givaro
37 |
38 | #include "givaro/givpoly1dense.h"
39 | // #include "givaro/givvectorsparse.h"
40 | // -- should be included in specialized class #include "givaro/givvectops.inl"
41 | #include "givaro/givpoly1denseops.inl"
42 | // #include "givaro/givvectsparseops.inl"
43 |
44 | #endif // __GIVARO_poly1_H
45 |
--------------------------------------------------------------------------------
/examples/FiniteFieldArithmetic.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/ellipticCurve.h"
2 |
3 | using namespace Givaro;
4 |
5 | int main()
6 | {
7 | int p,m;
8 | std::cin>>p>>m;
9 | ExtensionField E(p, m);
10 | typedef ExtensionField::Element e;//polynomial element
11 | e A,B,R;
12 | std::cout<<"1-Add, 2-Sub, 3-Mul, 4-Div, 5-Inv, 6-Neg, 7-Sqr, 8-Scalar multiply";
13 |
14 | std::cout<<"Write A";
15 | E.readElement(A,true);
16 | std::cout<<"Write B";
17 | E.readElement(B,true);
18 | Integer n;
19 | std::cin>>n;
20 | switch(1)
21 | {
22 | case 1:
23 | E.add(R,A,B);
24 | E.writeElement(A);
25 | std::cout<<" + ";
26 | E.writeElement(B);
27 | std::cout<<"=";
28 | E.writeElement(R);
29 | std::cout<
16 |
17 | namespace Givaro {
18 | // --
19 | template
20 | std::istream& Poly1Dom::read ( std::istream& sin )
21 | {
22 | char ch;
23 | sin >> std::ws >> ch;
24 | #ifdef GIVARO_DEBUG
25 | if (ch != '(')
26 | GivError::throw_error(
27 | GivBadFormat("Poly1Dom::read: syntax error no '('"));
28 | #endif
29 |
30 | _domain.read(sin);
31 |
32 | sin >> std::ws >> ch;
33 | #ifdef GIVARO_DEBUG
34 | if (ch != ',')
35 | GivError::throw_error(
36 | GivBadFormat("Poly1Dom::read: syntax error no ','"));
37 | #endif
38 |
39 | sin >> _x;
40 |
41 | sin >> std::ws >> ch;
42 | #ifdef GIVARO_DEBUG
43 | if (ch != ')')
44 | GivError::throw_error(
45 | GivBadFormat("Poly1Dom::read: syntax error no ')'"));
46 | #endif
47 | return sin;
48 | }
49 |
50 | template
51 | std::ostream& Poly1Dom::write( std::ostream& o ) const
52 | {
53 | return _domain.write(o) << '[' << _x << ']';
54 | }
55 |
56 |
57 |
58 | template
59 | std::ostream& Poly1Dom::write( std::ostream& o, const Rep& R) const
60 | {
61 | if (R.size()) {
62 | Rep P; assign(P, R);
63 | setdegree(P);
64 | if (P.size()) {
65 | if (! _domain.isZero(P[0])) {
66 | if (_domain.isOne(P[0]))
67 | _domain.write(o,P[0]);
68 | else
69 | _domain.write(o << "(",P[0]) << ")";
70 | }
71 | if (P.size() > 1) {
72 | if (! _domain.isZero(P[0])) o << " + ";
73 | if (! _domain.isZero(P[1])) {
74 | if (! _domain.isOne(P[1])) {
75 | _domain.write(o << "(",P[1]) << ")*";
76 | }
77 | o << _x;
78 | }
79 | for(unsigned long l=2;l
96 | std::istream& Poly1Dom::read ( std::istream& i, Rep& P) const
97 | {
98 | long deg;
99 | i >> deg;
100 | init(P,Degree(deg));
101 | // JGD 18.09.2002
102 | for(;deg>=0;--deg)
103 | _domain.read( i, P[(size_t)deg]);
104 | // i >> P[deg];
105 | return i;
106 | }
107 | template
108 | std::istream& Poly1Dom::read ( std::istream& i, Rep& P, bool flag) const //Pooja for easy input
109 | {
110 | if(flag)
111 | return Poly1Dom::read(i,P);
112 | long deg;
113 | i >> deg;
114 | init(P,Degree(deg));
115 | // JGD 18.09.2002
116 | long index;
117 | i>>index;
118 | while(index>-1&&index<=deg)
119 | {
120 | _domain.read( i, P[(size_t)index]);
121 | i>>index;
122 | }
123 |
124 | return i;
125 | }
126 | } // Givaro
127 | #endif // __GIVARO_poly1_io_INL
128 |
--------------------------------------------------------------------------------
/src/ellipticCurve.h:
--------------------------------------------------------------------------------
1 | /*
2 | check if "=="" operator for type Element in ecPoint is defined
3 | */
4 | #ifndef GIVARO_ZPZ_H
5 | #define GIVARO_ZPZ_H
6 | #include
7 | #include
8 | #endif
9 |
10 | #include
11 |
12 | using namespace Givaro;
13 |
14 |
15 | class ExtensionField
16 | {
17 | public:
18 | Integer p,m;
19 | typedef ZpzDom primeField;
20 | typedef Poly1Dom< primeField, Dense >::Element Element;
21 | primeField Fp;
22 | // Fp[X]- Polynomials over Fp, with X as indeterminate
23 | Poly1Dom< primeField, Dense > Fp_X;
24 | //irred is an irreducible polynomial of degree m in Fp_X
25 | Element irred,zero,one,mOne;
26 |
27 | ExtensionField(Integer p, Integer m);
28 |
29 | ExtensionField operator=(const ExtensionField& E);
30 | //Return R=(A+B)%p
31 | Element& add(Element& R, const Element& A, const Element& B) const;
32 | Element& addin(Element& R, const Element& A) const;
33 | //Return R=(A-B)%p
34 | Element& sub(Element& R, const Element& A, const Element& B) const;
35 | //Return R=-B
36 | Element& neg(Element& R, const Element& A) const;
37 | //Return R=A*B%irred
38 | Element& mul(Element& R, const Element& A, const Element& B) const;
39 | //Return R=A*A%irred
40 | Element& sqr(Element& R, const Element& A) const;
41 | //Return inverse of (A) with irred polynomial, if gcd(A,irred)!=1, then it return 0
42 | Element& inv(Element& I, const Element& A) const;
43 | //I+A=0
44 | Element& additiveInv(Element& I, const Element& A) const;
45 | //Return Q, such that Q=A/B=A*(inverse of B),
46 | Element& div(Element& Q, const Element& A, const Element& B) const;
47 | //R=k*A;
48 | Element& scalarMultiply(Element& R,const Element& A,Integer k) const;
49 |
50 | void readElement(Element& A, bool flag=true);
51 | void writeElement(Element& A);
52 |
53 | bool isElement(const Element& A);
54 | };
55 | class ecPoint
56 | {
57 | public:
58 | typedef ExtensionField::Element Element;
59 | ecPoint() : identity(true) {}
60 | ecPoint(bool b);
61 | ecPoint(Element x1, Element y1);
62 | ecPoint operator=( const ecPoint& P);
63 | bool operator==(const ecPoint& t) const;
64 | bool operator< (const ecPoint& t) const;
65 |
66 | bool identity;
67 | Element x, y;
68 | };
69 |
70 | /*
71 | Elliptic Curve over field p^m, defined by co-efficient a,b,c (3 possible equations)
72 | type 0: E/K, char(K)!=2: y2 = x3+ax+b,
73 | type 1: non-supersingular E/F2m: y2 + xy = x3+ax2+b,
74 | tyep 2: supersingular E/F2m: y2 + cy = x3 + ax + b
75 | */
76 |
77 | class ellipticCurve
78 | {
79 | public:
80 |
81 | typedef ExtensionField::Element Element;//element over the field
82 | ExtensionField* Kptr; //elliptic curve over field K
83 | Element A,B,C; //equation of curve, depending upon the char(K)
84 |
85 | ellipticCurve();
86 | ~ellipticCurve();
87 |
88 | ellipticCurve operator=( const ellipticCurve& F);
89 | void print();
90 | int type; //0,1,2
91 | };
92 |
93 | class ellipticCurveFq
94 | {
95 | public:
96 | ellipticCurve* ec;
97 | int d; //elliptic curve ec/Fq, abelian group of points E(Fq^d), default d=1
98 | typedef ExtensionField::Element fieldElement;
99 | typedef ecPoint Point;
100 | ExtensionField* field;//coordinates of point belong to this field F(q^d)
101 | //hence arithmetic on co-ordinates is done in this field
102 | Point identity;
103 | ellipticCurveFq();
104 | ellipticCurveFq(ellipticCurve* e);
105 | ~ellipticCurveFq();
106 | //Q=-P
107 | const Point& inv(Point& Q, const Point &P);
108 | //is Q=-P?
109 | bool isInv(const Point& Q, const Point &P);
110 | //R=2*P
111 | Point& Double(Point &R,Point &P);
112 | //R=P+Q
113 | Point& add(Point &R,Point &P, Point &Q);
114 | //R=k*P
115 | Point& scalarMultiply(Point&R, Point& P, Integer k, Integer order);//order of P
116 | //R=a*P+b*Q
117 | void compute(ecPoint& R,Integer a, ecPoint& P,Integer b,ecPoint& Q,Integer n);//ord(P)=n
118 | bool verifyPoint(const Point &P) const;
119 | void show(Point& P);
120 | void show();
121 |
122 | };
--------------------------------------------------------------------------------
/src/ECC.h:
--------------------------------------------------------------------------------
1 | #ifndef EC_H
2 | #define EC_H
3 | #include "ellipticCurve.h"
4 | #endif
5 |
6 | class Key
7 | {
8 | public:
9 | ecPoint Q;
10 | Integer d;//Q=dP
11 | };
12 | class publicKey
13 | {
14 | public:
15 | ellipticCurveFq* E_Fq_ptr;
16 | ecPoint* basePoint_ptr;
17 | Integer n; //order of basePoint
18 | ecPoint* Q_ptr; //Q=d*P, where d is private
19 | };
20 | class SignatureECDSA
21 | {
22 | public:
23 | Integer r,s;
24 | };
25 | class SignatureELGAMAL
26 | {
27 | public:
28 | Integer s;
29 | ecPoint R;
30 | };
31 | /*Input: R is x-coordinate of point in E(Fq) represented by E_Fq and mod = Order(basepoint)
32 | Output: Computes result=f(R), 0<=result*/
47 | bool publicKeyValidation(ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n);
48 |
49 | /*ECDSA Signature Generation
50 | Input: Secret Key K, message m to be signed, basepoint P in E(Fq) represented by E_Fq, n=order(P)
51 | Output: Signature S for the message*/
52 | void SignatureGeneration(SignatureECDSA& S, Key& K,Integer& message,ecPoint& P,ellipticCurveFq& E_Fq,Integer& n);
53 |
54 | /*ECDSA Signature Verification
55 | Input: Signature S for the message m, Secret Key K, basepoint P in E(Fq) represented by E_Fq, n=order(P), Q=d*P where d is private key
56 | Output: returns true if message is signed*/
57 | bool SignatureVerification(SignatureECDSA& S,Integer& message,ecPoint& P,ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n);
58 |
59 | /*ELGAMAL Signature Generation
60 | Input: Secret Key K, message m to be signed, basepoint P in E(Fq) represented by E_Fq, n=order(P)
61 | Output: Signature S for the message*/
62 | void SignatureGeneration(SignatureELGAMAL& S, Key& K,Integer& message,ecPoint& P,ellipticCurveFq& E_Fq,Integer& n);
63 |
64 | /*ELGAMAL Signature Verification
65 | Input: Signature S for the message m, Secret Key K, basepoint P in E(Fq) represented by E_Fq, n=order(P), Q=d*P where d is private key
66 | Output: returns true if message is signed*/
67 | bool SignatureVerification(SignatureELGAMAL& S,Integer& message,ecPoint& P,ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n);
68 |
69 | /*prints Signature of a message m(an Ineger) generated by ECDSA*/
70 | void showSignature(SignatureECDSA& S);
71 |
72 | /*prints Signature of a message m(an Ineger) generated by ELGAMAL*/
73 | void showSignature(SignatureELGAMAL& S,ellipticCurveFq& E_Fq);
74 |
75 | /*To input ELGAMAL Signature S as told by the signee of message*/
76 | void inputSignature(SignatureELGAMAL& S,ellipticCurveFq& E_Fq);
77 |
78 | /*To input ECDSA Signature S as told by the signee of message*/
79 | void inputSignature(SignatureECDSA& S);
80 |
81 | /*Input: basepoint P in E(Fq) represented by E_Fq, n=order(P)
82 | Output: Ka- public Key with Alice, Kb- public Key with Bob
83 | a and b: secret integer by Alice and Bob respectively*/
84 | void DiffieHellmanKeyExchange(Integer& a, Integer& b, ecPoint& Ka,ecPoint& Kb,ecPoint& P,ellipticCurveFq& E_Fq,Integer& n);
85 |
86 | /*Input: message m and E(Fq)
87 | Output: Point representation of m as M ∈ E(Fq)
88 | This function is not yet defined*/
89 | void integerToPoint(ecPoint& M,Integer& m, ellipticCurveFq& E_Fq);
90 |
91 | /*Input: message represented as a Point in E(Fq), basepoint P in E(Fq) represented by E_Fq, n=order(P)
92 | Output: Encrypted message {M1,M2} */
93 | void EncryptionELGAMAL(ecPoint& M1, ecPoint& M2, ecPoint& P,ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n, ecPoint& message);
94 |
95 | /*Input: Encrypted message {M1,M2}, basepoint P in E(Fq) represented by E_Fq, n=order(P)
96 | Output: message represented as a Point in E(Fq)*/
97 | void DecryptionELGAMAL(ecPoint& message, Integer& d, ecPoint& P,ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n, ecPoint& M1, ecPoint& M2);
98 |
--------------------------------------------------------------------------------
/src/ECC.cpp:
--------------------------------------------------------------------------------
1 | #include "ECC.h"
2 |
3 | using namespace std;
4 |
5 | //Algorithm 4.24 Key pair generation
6 | void convertElementToInt(Integer& result,ExtensionField::Element& R, Integer& mod, ellipticCurveFq& E_Fq)
7 | {
8 | result=0;
9 | ExtensionField::Element P;
10 | if (R.size())
11 | {
12 | E_Fq.field->Fp_X.assign(P, R);
13 | E_Fq.field->Fp_X.setdegree(P);
14 | for(unsigned long l=0;l, ord(P)=n,
37 | {
38 | if(Q.identity)
39 | return false;
40 | if(!(E_Fq.field->isElement(Q.x)&&E_Fq.field->isElement(Q.y)))
41 | return false;
42 | if(!E_Fq.verifyPoint(Q))
43 | return false;
44 | ecPoint T;
45 | E_Fq.scalarMultiply(T,Q,n,n);
46 | if(!T.identity)
47 | return false;
48 | return true;
49 | }
50 |
51 | /*Algorithm 4.29 ECDSA signature generation*/
52 | //Assumption: H(x) gives a number of bitlength <= n
53 | void SignatureGeneration(SignatureECDSA& S, Key& K,Integer& message,ecPoint& P,ellipticCurveFq& E_Fq,Integer& n)
54 | {
55 | Integer k,_x=1,e;
56 | ecPoint temp;
57 | do
58 | {
59 | do
60 | {
61 | Integer::random_lessthan (k,n);
62 | E_Fq.scalarMultiply(temp,P,k,n);
63 | convertElementToInt(_x,temp.x,n,E_Fq);
64 | S.r=_x%n;
65 | }while(S.r==0);
66 | e=H(message,n);
67 | invin(k,n);
68 | S.s=((e+K.d*S.r)*k)%n;
69 | }while(S.s==0);
70 | }
71 | /*Algorithm 4.30 ECDSA signature verification*/
72 | bool SignatureVerification(SignatureECDSA& S,Integer& message,ecPoint& P,ecPoint& Q,ellipticCurveFq& E_Fq,Integer& n)
73 | {
74 | if(S.r>n-1||S.r<1||S.s>n-1||S.s<1)
75 | return false;
76 | Integer e,w,u1,u2;
77 | ecPoint X;
78 | e=H(message,n);
79 | inv(w,S.s,n);
80 | u1=(e*w)%n;
81 | u2=(S.r*w)%n;
82 | E_Fq.compute(X,u1,P,u2,Q,n);
83 | if(X.identity)
84 | return false;
85 | convertElementToInt(e,X.x,n,E_Fq);
86 | w=e%n;
87 | if(w==S.r)
88 | return true;
89 | return false;
90 | }
91 | //Assumption: m>S.s;
155 | std::cout<<"give (x,y) of Point R in Signature: ";
156 | E_Fq.field->readElement(S.R.x);
157 | E_Fq.field->readElement(S.R.y);
158 | }
159 | void inputSignature(SignatureECDSA& S)
160 | {
161 | cin>>S.s>>S.r;
162 | }
163 | void showSignature(SignatureECDSA& S)
164 | {
165 | cout<<"s: "<field.p, E_Fq->field.m);
178 | E_Fq->field.Fp_X.assign(acc,Fp_X.zero);
179 | ();
180 |
181 | integerToElement(messageE,message,E_Fq->field);
182 | for(int j=0;j<100;j++)
183 | {
184 | E_Fq->field.scalarMultiply(temp,messageE,(Integer)100);
185 | E_Fq->field.add(Xj,temp,acc);
186 | compute();
187 | }
188 |
189 | }*/
--------------------------------------------------------------------------------
/src/attacksECC.cpp:
--------------------------------------------------------------------------------
1 | /*INPUT: P ∈ E(Fq) of prime order n, Q ∈ ⟨P⟩.
2 | OUTPUT: The discrete logarithm l = logP Q.*/
3 |
4 | #include "attacksECC.h"
5 |
6 | using namespace Givaro;
7 | using namespace std;
8 |
9 | #define NumberOfPartitions_Pollard 16
10 | #define pollardThreshold 10 //Pollard rho would try 10 times
11 | #define noMatchThreshold 50
12 |
13 | Integer& H(Integer& result,ecPoint& input, int L, ellipticCurveFq& E_Fq)
14 | {
15 | Integer mod=(Integer)L;
16 | //Integer::random_lessthan (result,mod);
17 | ExtensionField::Element P,R=input.x,Q=input.y;
18 | if (R.size())
19 | {
20 | E_Fq.field->Fp_X.assign(P, R);
21 | E_Fq.field->Fp_X.setdegree(P);
22 | for(unsigned long l=0;lFp_X.assign(P, Q);
31 | E_Fq.field->Fp_X.setdegree(P);
32 | for(unsigned long l=0;l>L;
63 | }
64 | Integer a[L],b[L];
65 | Integer c1,c2,d1,d2;
66 | //a=(Integer*)malloc(sizeof(Integer)*L);
67 | //b=(Integer*)malloc(sizeof(Integer)*L);
68 |
69 | ecPoint R[L],P1,P2,tP;
70 | Integer::seeding();
71 |
72 | for(int i=0; ipollardThreshold)
82 | {
83 | cout<<"pollard rho method failed to compute, try giving your own initial number c1 and d1"<noMatchThreshold)
113 | {
114 | cout<<"pollard rho method failed to compute, try changing partition function"<& a,std::vector& p)
151 | {
152 | Integer length=p.size();
153 | Integer n=1;
154 | for(Integer i=0;i m(length),c(length);
157 | for(Integer i=0;i IP;
169 |
170 | std::vector Lf;
171 | std::vector Le;
172 | IP.set(Lf,Le,n,0);
173 | Integer length=Lf.size();
174 | cout< res(length);
176 | ecPoint P0,_Q,temp1,temp2,S;
177 | Integer z, power,f;
178 | for(Integer i=0;ip=p;
12 | this->m=m;
13 | Fp=primeField((primeField::Residu_t)p);
14 | Fp_X=Poly1Dom< primeField, Dense >( Fp, Indeter("X") );
15 | if(m==1)
16 | Fp_X.assign(irred,(Element)p);
17 | else
18 | {
19 |
20 | cout<<"Give an irreducible polynomial of degree "<1)
70 | {
71 | Element tmp,Q;
72 | Fp_X.mul(tmp,A,B);
73 | Fp_X.divmod(Q,R,tmp,irred);
74 | }
75 | else
76 | Fp_X.mul(R,A,B);
77 | return R;
78 | }
79 | //Return R=A*A%irred
80 | ExtensionField::Element& ExtensionField::sqr(Element& R, const Element& A) const
81 | {
82 | if(m>1)
83 | {
84 | Element tmp,Q;
85 | Fp_X.sqr(tmp,A);
86 | Fp_X.divmod(Q,R,tmp,irred);
87 | }
88 | else
89 | Fp_X.sqr(R,A);
90 | return R;
91 | }
92 | //Return inverse of (A) with irred polynomial, if gcd(A,irred)!=1, then it return 0
93 | ExtensionField::Element& ExtensionField::inv(Element& I, const Element& A) const
94 | {
95 | Element tmp,D;
96 | D=Fp_X.gcd(D,I,tmp,A,irred);
97 | if(Fp_X.isOne(D))
98 | return I;
99 | Fp_X.assign(I,Fp_X.zero);
100 | return I;
101 |
102 | }
103 | ExtensionField::Element& ExtensionField::additiveInv(Element& I, const Element& A) const
104 | {
105 | Fp_X.sub(I,Fp_X.zero,A);
106 | return I;
107 |
108 | }
109 |
110 | //Return Q, such that Q=A/B=A*(inverse of B),
111 | ExtensionField::Element& ExtensionField::div(Element& Q, const Element& A, const Element& B) const
112 | {
113 | Element I;
114 | I=inv(I,B);
115 | mul(Q,A,I);
116 | return Q;
117 | }
118 | ExtensionField::Element& ExtensionField::scalarMultiply(Element& R,const Element& A,Integer k) const
119 | {
120 | k=k%p;
121 | if(m==1)
122 | {
123 | Element eK;
124 | primeField::Element tmp;
125 | Fp_X.assign(eK,Fp.init(tmp,k));
126 | Fp_X.mul(R,A,eK);
127 | return R;
128 | }
129 | Element tmp,acc=A;
130 | Fp_X.assign(R,zero);
131 | while(k>0)
132 | {
133 | if(k%2)
134 | Fp_X.addin(R,acc);
135 | acc=Fp_X.add(tmp,acc,acc); //acc=tmp=2*acc
136 | k=k/2;
137 | }
138 | return R;
139 | }
140 | void ExtensionField::readElement(Element& P, bool flag)
141 | {
142 | Fp_X.read(cin,P,flag);
143 | }
144 | void ExtensionField::writeElement(Element& A)
145 | {
146 | cout<<"( ";
147 | Fp_X.write(cout<<"",A);
148 | cout<<" )";
149 | }
150 | bool ExtensionField::isElement(const Element& A)
151 | {
152 | Degree d=Fp_X.degree(A);
153 | if(d._degidentity=true;
172 | return *this;
173 | }
174 |
175 | this->identity=P.identity;
176 | this->x=P.x;
177 | this->y=P.y;
178 | return *this;
179 | }
180 | bool ecPoint::operator==(const ecPoint& t) const
181 | {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);}
182 | bool ecPoint::operator< (const ecPoint& t) const
183 | {return identity ? !t.identity : (!t.identity && (x>p>>m;
191 | Kptr=new ExtensionField(p,m);
192 | cout<<"Write A: ";
193 | Kptr->readElement( A);
194 | cout<<"Write B: ";
195 | Kptr->readElement( B);
196 | cout<<"type? ";
197 | cin>>type;
198 | if(type==2)
199 | {
200 | cout<<"Write C: ";
201 | Kptr->readElement( C);
202 | }
203 | cout<writeElement(A);
224 | cout<writeElement(B);
227 | cout<writeElement(C);
230 | cout<>d;
239 | if(d!=1)
240 | field=new ExtensionField(ec->Kptr->p,(ec->Kptr->m)*d);
241 | else
242 | field=ec->Kptr;
243 | identity.identity=true;
244 | this->d=d;
245 | }
246 | ellipticCurveFq::ellipticCurveFq(ellipticCurve* e)
247 | {
248 | ec=e;
249 | cout<<"degree d? ";
250 | cin>>d;
251 | if(d!=1)
252 | field=new ExtensionField(ec->Kptr->p,(ec->Kptr->m)*d);
253 | else
254 | field=ec->Kptr;
255 | identity.identity=true;
256 | this->d=d;
257 | }
258 | ellipticCurveFq::~ellipticCurveFq()
259 | {
260 | free(ec);
261 | free(field);
262 | }
263 | const ellipticCurveFq::Point& ellipticCurveFq::inv(Point& Q, const Point &P)
264 | {
265 | if(P.identity)
266 | {
267 | Q.identity=true;
268 | return Q;
269 | }
270 | Q.identity=false;
271 | Point T;
272 | switch(ec->type)
273 | {
274 | case 0:
275 | Q.x=P.x;
276 | field->additiveInv(Q.y,P.y); //Q.y+P.y=0
277 | return Q;
278 |
279 | case 1:
280 | Q.x=P.x;
281 | field->add(Q.y,P.y,P.x);
282 | //Q.y+=Q.x;
283 | return Q;
284 |
285 | case 2:
286 | Q.x=P.x;
287 | field->add(Q.y,P.y,ec->C);
288 |
289 | //Q.y+=ec->C;
290 | return Q;
291 | default:
292 | return Q;
293 |
294 | }
295 | }
296 | bool ellipticCurveFq::isInv(const Point& Q, const Point &P) //is Q+P=point at inifinity?
297 | {
298 | Point R;
299 | inv(R,P);
300 | //cout<<"At inverse check"; show(R);
301 | if(R==Q)
302 | return true;
303 | return false;
304 | }
305 |
306 | ellipticCurveFq::Point& ellipticCurveFq::Double(Point &R,Point &P)
307 | {
308 | if (P.identity||isInv(P,P))
309 | {
310 | R.identity=true;
311 | return R;
312 | }
313 |
314 | R.identity=false;
315 | fieldElement x,y,x12;
316 | fieldElement slopeSquare, slope;
317 | field->sqr(x12,P.x);
318 | fieldElement _3x12,_2y,_3x12pA,_2x,_x,slope_x;
319 | fieldElement xpy,Bdx12,slopex,slopex_x;
320 | fieldElement x12pA,ypC,xpx,slopexpx;
321 | switch(ec->type)
322 | {
323 | case 0:
324 |
325 | field->scalarMultiply(_3x12,x12,3);
326 | field->scalarMultiply(_2y,P.y,2);
327 | field->add(_3x12pA,_3x12,ec->A);
328 | field->div(slope,_3x12pA,_2y);
329 | field->sqr(slopeSquare,slope);
330 | field->scalarMultiply(_2x,P.x,2);
331 | field->sub(x,slopeSquare,_2x);
332 | field->sub(_x,P.x,x);
333 | field->sub(y,field->mul(slope_x,slope,_x),P.y);
334 |
335 | R.x=x;
336 | R.y=y;
337 | return R;
338 |
339 | case 1:
340 |
341 | field->add(xpy,x12,P.y);
342 | field->div(slope,xpy,P.x);
343 | field->div(Bdx12,ec->B,x12);
344 | field->add(x,x12,Bdx12);
345 | field->mul(slopex,slope,x);
346 | field->add(slopex_x,slopex,x);
347 | field->add(y,x12,slopex_x);
348 | R.x=x;
349 | R.y=y;
350 | return R;
351 | case 2:
352 |
353 | field->add(x12pA,x12,ec->A);
354 | field->div(slope,x12pA,ec->C);
355 | field->sqr(slopeSquare,slope);
356 | x=slopeSquare;
357 | field->add(ypC,P.y,ec->C);
358 | field->add(xpx,P.x,x);
359 | field->mul(slopexpx,xpx,slope);
360 | field->add(y,ypC,slopexpx);
361 | R.x=x;
362 | R.y=y;
363 | return R;
364 | }
365 | return R;
366 | }
367 | ellipticCurveFq::Point& ellipticCurveFq::add(Point &R,Point &P, Point &Q)
368 | {
369 | if(P.identity&&Q.identity||isInv(P,Q))
370 | {
371 | R.identity=true;
372 | return R;
373 | }
374 | R.identity=false;
375 | if (P.identity)
376 | {
377 | R.x=Q.x;
378 | R.y=Q.y;
379 | return R;
380 | }
381 | if (Q.identity)
382 | {
383 | R.x=P.x;
384 | R.y=P.y;
385 | return R;
386 | }
387 | if(P==Q)
388 | return Double(R,P);
389 |
390 | fieldElement x,y,x12;
391 | fieldElement slopeSquare, slope;
392 | fieldElement y2m1,x2m1,x1p2,x1m3,slopex1m3,y1pC,x1p2pA,x1p2pApS,slopex1m3px3;
393 | field->sub(y2m1,Q.y,P.y);
394 | field->sub(x2m1,Q.x,P.x);
395 | field->div(slope,y2m1,x2m1);
396 | field->sqr(slopeSquare,slope);
397 | field->add(x1p2,P.x,Q.x);
398 | switch(ec->type)
399 | {
400 | case 0:
401 | field->sub(x,slopeSquare,x1p2);
402 | field->sub(x1m3,P.x,x);
403 | field->mul(slopex1m3,slope,x1m3);
404 | field->sub(y,slopex1m3,P.y);
405 | R.x=x;
406 | R.y=y;
407 | return R;
408 | case 1:
409 | field->add(x1p2pA,x1p2,ec->A);
410 | field->add(x1p2pApS,x1p2pA,slope);
411 | field->add(x,x1p2pApS,slopeSquare);
412 | field->add(x1m3,P.x,x);
413 | field->mul(slopex1m3,slope,x1m3);
414 | field->add(slopex1m3px3,slopex1m3,x);
415 | field->add(y,slopex1m3px3,P.y);
416 | R.x=x;
417 | R.y=y;
418 | return R;
419 | case 2:
420 | field->add(x,slopeSquare,x1p2);
421 | field->add(x1m3,P.x,x);
422 | field->mul(slopex1m3,slope,x1m3);
423 | field->add(y1pC,P.y,ec->C);
424 | field->add(y,y1pC,slopex1m3);
425 | R.x=x;
426 | R.y=y;
427 | return R;
428 | }
429 | return R;
430 | }
431 | void ellipticCurveFq::show(Point& P)
432 | {
433 | if(P.identity)
434 | {
435 | cout<<"o";
436 | return;
437 | }
438 |
439 | cout<<"(";
440 | field->writeElement(P.x);
441 | cout<<", ";
442 | field->writeElement(P.y);
443 | cout<<")";
444 | }
445 | //R=kP
446 | ellipticCurveFq::Point& ellipticCurveFq::scalarMultiply(Point&R, Point& P, Integer k, Integer order)//order of P
447 | {
448 | if(P.identity)
449 | {
450 | R.identity=true;
451 | return R;
452 | }
453 | Point temp(false);
454 | R.identity=true;
455 | Point acc(P);
456 | if(order!=-1)//if order is known
457 | k=k%order;//better: k=k%order(P)
458 | while(k>0)
459 | {
460 | if(k%2)
461 | {
462 | /*if(k==1)
463 | {
464 | show(R);
465 | show(acc);
466 | }*/
467 | add(temp,R,acc);
468 | R=temp;
469 | }
470 | Double(temp,acc);
471 | acc=temp;
472 | k=k/2;
473 | }
474 | return R;
475 | }
476 | bool ellipticCurveFq::verifyPoint(const Point &P) const
477 | {
478 | if(P.identity)
479 | return true;
480 | fieldElement rhs,x2,y2,x2pAx,x2pA,xpA,xpAx2,lhs,xy,cy;
481 | field->sqr(x2,P.x);
482 | field->sqr(y2,P.y);
483 |
484 | switch (ec->type)
485 | {
486 | case 0:
487 | field->add(x2pA,x2,ec->A);
488 | field->mul(x2pAx,x2pA,P.x);
489 | field->add(rhs,x2pAx,ec->B);
490 | /*field->writeElement(rhs)<writeElement(y2)<add(xpA,P.x,ec->A);
499 | field->mul(xpAx2,xpA,x2);
500 | field->add(rhs,xpAx2,ec->B);
501 | field->mul(xy,P.x,P.y);
502 | field->add(lhs,y2,xy);
503 | if(lhs==rhs)
504 | return true;
505 | else
506 | return false;
507 | case 2:
508 | field->add(x2pA,x2,ec->A);
509 | field->mul(x2pAx,x2pA,P.x);
510 | field->add(rhs,x2pAx,ec->B);
511 | field->mul(cy,ec->C,P.y);
512 | field->add(lhs,y2,cy);
513 | if(lhs==rhs)
514 | return true;
515 | else
516 | return false;
517 | default:
518 | return false;
519 | }
520 | }
521 | /*type 0: E/K, char(K)!=2: y2 = x3+ax+b,
522 | type 1: non-supersingular E/F2m: y2 + xy = x3+ax2+b,
523 | tyep 2: supersingular E/F2m: y2 + cy = x3 + ax + b*/
524 | void ellipticCurveFq::show()
525 | {
526 | cout<<"Elliptic Curve Defined by ";
527 | switch(ec->type)
528 | {
529 | case 0:
530 | cout<<"y^2 = x^3 + ";
531 | field->writeElement(ec->A);
532 | cout<<"x + ";
533 | field->writeElement(ec->B);
534 | cout<writeElement(ec->A);
539 | cout<<"x^2 + ";
540 | field->writeElement(ec->B);
541 | cout<writeElement(ec->C);
546 | cout<<"y = x^3 + ";
547 | field->writeElement(ec->A);
548 | cout<<"x + ";
549 | field->writeElement(ec->B);
550 | cout<p<<"^"<m;
554 | cout<<" with irreducible polynomial ";
555 | field->writeElement(field->irred);
556 | cout<