1 /*
2 * Digital Signature Standard (DSS)
3 *
4 * Elliptic Curve variation GF(2^m) - See Dr. Dobbs Journal, April 1997
5 *
6 * This program asks for the name of a <file>, computes its message digest,
7 * signs it, and outputs the signature to a file <file>.ecs. It is assumed
8 * that curve parameters are available from a file common2.ecs, as well as
9 * the private key of the signer previously generated by the ecsgen2 program
10 *
11 * The curve is y^2+xy = x^3+Ax^2+B over GF(2^m) using a trinomial or
12 * pentanomial basis (t^m+t^a+1 or t^m+t^a+t^b+t^c+1), These parameters
13 * can be generated using the findbase.cpp example program, or taken from tables
14 * provided, for example in IEEE-P1363 Annex A
15 *
16 * The file common2.ecs is presumed to exist and contain
17 * {m,A,B,q,x,y,a,b,c} where A and B are parameters of the equation
18 * above, (x,y) is an initial point on the curve, {m,a,b,c} are the field
19 * parameters, (b is zero for a trinomial) and q is the order of the
20 * (x,y) point, itself a large prime. The number of points on the curve is
21 * cf.q where cf is the "co-factor", normally 2 or 4.
22 *
23 * This program is written for static mode.
24 * For a 163-bit modulus p, MR_STATIC could be defined as 6 in mirdef.h
25 * for a 32-bit processor, or 11 for a 16-bit processor (11*16 > 163).
26 * The system parameters can be found in the file common2.ecs
27 * Assumes MR_GENERIC_MT is defined in mirdef.h
28 */
29
30 #include <stdio.h>
31 #include "miracl.h"
32 #include <stdlib.h>
33 #include <string.h>
34
strip(char * name)35 void strip(char *name)
36 { /* strip off filename extension */
37 int i;
38 for (i=0;name[i]!='\0';i++)
39 {
40 if (name[i]!='.') continue;
41 name[i]='\0';
42 break;
43 }
44 }
45
hashing(miracl * mip,FILE * fp,big hash)46 static void hashing(miracl *mip,FILE *fp,big hash)
47 { /* compute hash function */
48 char h[20];
49 int i,ch;
50 sha sh;
51 shs_init(&sh);
52 while ((ch=fgetc(fp))!=EOF) shs_process(&sh,ch);
53 shs_hash(&sh,h);
54 bytes_to_big(mip,20,h,hash);
55 }
56
main()57 int main()
58 {
59 FILE *fp;
60 int m,a,b,c;
61 char ifname[50],ofname[50];
62 big a2,a6,q,x,y,d,r,s,k,hash;
63 epoint *g;
64 long seed;
65 miracl instance;
66 miracl *mip=&instance;
67 char mem[MR_BIG_RESERVE(10)]; /* reserve space on the stack for 10 bigs */
68 char mem1[MR_ECP_RESERVE(1)]; /* and one elliptic curve points */
69 memset(mem,0,MR_BIG_RESERVE(10));
70 memset(mem1,0,MR_ECP_RESERVE(1));
71
72 /* get public data */
73 fp=fopen("common2.ecs","rt");
74 if (fp==NULL)
75 {
76 printf("file common2.ecs does not exist\n");
77 return 0;
78 }
79 fscanf(fp,"%d\n",&m);
80
81 mip=mirsys(mip,MR_ROUNDUP(abs(m),4),16);
82 a2=mirvar_mem(mip,mem,0);
83 a6=mirvar_mem(mip,mem,1);
84 q=mirvar_mem(mip,mem,2);
85 x=mirvar_mem(mip,mem,3);
86 y=mirvar_mem(mip,mem,4);
87 d=mirvar_mem(mip,mem,5);
88 r=mirvar_mem(mip,mem,6);
89 s=mirvar_mem(mip,mem,7);
90 k=mirvar_mem(mip,mem,8);
91 hash=mirvar_mem(mip,mem,9);
92
93 innum(mip,a2,fp); /* curve parameters */
94 innum(mip,a6,fp); /* curve parameters */
95 innum(mip,q,fp); /* order of (x,y) */
96 innum(mip,x,fp); /* (x,y) point on curve of order q */
97 innum(mip,y,fp);
98
99 fscanf(fp,"%d\n",&a);
100 fscanf(fp,"%d\n",&b);
101 fscanf(fp,"%d\n",&c);
102 fclose(fp);
103
104 /* randomise */
105 printf("Enter 9 digit random number seed = ");
106 scanf("%ld",&seed);
107 getchar();
108 irand(mip,seed);
109
110 ecurve2_init(mip,m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE); /* initialise curve */
111
112 g=epoint_init_mem(mip,mem1,0);
113 epoint2_set(mip,x,y,0,g); /* set point of order q */
114
115 /* calculate r - this can be done offline,
116 and hence amortized to almost nothing */
117 bigrand(mip,q,k);
118 ecurve2_mult(mip,k,g,g); /* see ebrick2.c for method to speed this up */
119 epoint2_get(mip,g,r,r);
120 divide(mip,r,q,q);
121
122 /* get private key of signer */
123 fp=fopen("private.ecs","rt");
124 if (fp==NULL)
125 {
126 printf("file private.ecs does not exist\n");
127 return 0;
128 }
129 innum(mip,d,fp);
130 fclose(fp);
131
132 /* calculate message digest */
133 printf("file to be signed = ");
134 gets(ifname);
135 strcpy(ofname,ifname);
136 strip(ofname);
137 strcat(ofname,".ecs");
138 if ((fp=fopen(ifname,"rb"))==NULL)
139 {
140 printf("Unable to open file %s\n",ifname);
141 return 0;
142 }
143 hashing(mip,fp,hash);
144 fclose(fp);
145
146 /* calculate s */
147 xgcd(mip,k,q,k,k,k);
148
149 mad(mip,d,r,hash,q,q,s);
150 mad(mip,s,k,k,q,q,s);
151 fp=fopen(ofname,"wt");
152 otnum(mip,r,fp);
153 otnum(mip,s,fp);
154 fclose(fp);
155 /* clear all memory used */
156 memset(mem,0,MR_BIG_RESERVE(10));
157 memset(mem1,0,MR_ECP_RESERVE(1));
158
159 return 0;
160 }
161
162