KGC_TEST/KGC/miracl/source/ecdh2m.c

222 lines
7.4 KiB
C

/*
Example GF(2^m) Elliptic Curve Diffie-Hellman program for constrained environments. Uses point compression.
Stack-only memory allocation. 32-bit processor
Use with this mirdef.h header (for a PC using MS C)
#define MR_LITTLE_ENDIAN
#define MIRACL 32
#define mr_utype int
#define MR_IBITS 32
#define MR_LBITS 32
#define mr_unsign32 unsigned int
#define mr_dltype long long
#define mr_unsign64 unsigned long long
#define MR_STATIC 6
#define MR_ALWAYS_BINARY
#define MR_NOASM
#define MR_STRIPPED_DOWN
#define MR_GENERIC_MT
#define MAXBASE ((mr_small)1<<(MIRACL-1))
#define MR_BITSINCHAR 8
#define MR_NOKOBLITZ
#define MR_NO_SS
#define MR_SIMPLE_BASE
#define MR_SIMPLE_IO
and also possibly
#define MR_NO_FILE_IO
#define MR_NO_STANDARD_IO
To reduce size further consider using your own random number generator
#define MR_NO_RAND
On some older Microsoft compilers it may be necessary to substitute __int64 for
long long
Also consider NOT using precomputation (use ecurve2_mult(.) instead of mul2_brick(.)), and
go through each of the modules below and carefully delete unused functions..
And do not use point compression??
Build the library from these modules (Example using MS C compiler)
cl /c /O2 /W3 mrcore.c
cl /c /O2 /W3 mrarth0.c
cl /c /O2 /W3 mrarth1.c
cl /c /O2 /W3 mrio1.c
cl /c /O2 /W3 mrbits.c
cl /c /O2 /W3 mrgf2m.c
cl /c /O2 /W3 mrec2m.c
rem
rem Create library 'miracl.lib'
del miracl.lib
lib /OUT:miracl.lib mrbits.obj mrio1.obj
lib /OUT:miracl.lib miracl.lib mrarth0.obj mrarth1.obj mrcore.obj
lib /OUT:miracl.lib miracl.lib mrec2m.obj mrgf2m.obj
del mr*.obj
rem Create the program
cl /O2 ecdh2m.c miracl.lib
*/
#include <stdio.h>
#include <string.h>
#include "miracl.h"
#define HEXDIGS (MIRACL/4)
/* !!!!!! THIS CODE AND THESE ROMS ARE NOW CREATED AUTOMATICALLY USING THE ROMAKER2.C APPLICATION !!!!!!!! */
/* !!!!!! READ COMMENTS IN ROMAKER2.C !!!!!! */
#define CURVE_M 163
#define CURVE_A 7
#define CURVE_B 6
#define CURVE_C 3
/* NIST b163 bit elliptic curve Y^2+XY=X^3+A.X^2+B (from nist163.ecs). Irreducible polynomial
is x^163+x^7+x^6+x^3+1. Here is stored B, the group order q, and the generator G(x,y) */
static const mr_small rom[]=
{0x4A3205FD,0x512F7874,0x1481EB10,0xB8C953CA,0x0A601907,2,
0xA4234C33,0x77E70C12,0x000292FE,0,0,4,
0xE8343E36,0xD4994637,0xA0991168,0x86A2D57E,0xF0EBA162,3,
0x797324F1,0xB11C5C0C,0xA2CDD545,0x71A0094F,0xD51FBC6C,0};
#define WINDOW 4
/* 2^4 =16 precomputed points based on fixed generator G(x,y) */
/* (created using romaker2.c program with window size of 4) */
static const mr_small prom[]=
{0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,
0xe8343e36,0xd4994637,0xa0991168,0x86a2d57e,0xf0eba162,0x3,
0x797324f1,0xb11c5c0c,0xa2cdd545,0x71a0094f,0xd51fbc6c,0x0,
0x5fd9372,0xaa17fdf2,0x6648e974,0x31dd5c03,0x75f1f527,0x2,
0xdcf990e0,0x79117c6a,0x5d2ff662,0x9865bdb2,0xb0914960,0x0,
0x78a887a6,0xe478fe58,0x3d3d2364,0x3b85b263,0x34c6885e,0x5,
0xef273598,0xa6d7e436,0x53001bd9,0x75cc731c,0xbf414f74,0x3,
0x4f685f08,0x6f8daf88,0xd1c71b1f,0x6f4913ff,0xbaa8682a,0x2,
0xd5301336,0xb4f6dd1e,0x6454423b,0x4ebaf45,0x65c6e401,0x2,
0xa700c73d,0x6f842a26,0xe8f5f5fd,0x4db6da9,0x48fcdc95,0x6,
0x1db757cb,0xb5bf42ba,0xabfd25b4,0x466e5be3,0x2cf27012,0x7,
0xeb7ad12e,0x47e38e87,0x5f9c4ef1,0x2fcd5483,0x3893822e,0x0,
0x7c98bf09,0xa41f9589,0x680ca2a3,0xdfa83842,0xedd41659,0x1,
0xa3463d19,0xaf8c4bb0,0x2288658a,0x84b3c40d,0x90cd449b,0x2,
0x6bb4bf11,0x5e996afa,0x9b2ae97a,0xff211307,0xfbf58239,0x5,
0x4ab8c649,0x2fcf02ee,0x3c7efb85,0x76f09ad9,0xdbca45da,0x7,
0xeeba93af,0x59adf276,0xd25e3760,0x3292b2c1,0x271d1b84,0x4,
0x37f9391c,0xf423fd60,0xbf079624,0x4c9036e0,0x63075e19,0x4,
0xb726dfb5,0x38c349b3,0x6e0988b7,0x87b54141,0xcb8d73b,0x2,
0xd1acdb88,0x64ca1fcc,0x690dfa73,0xc6708b6f,0xb44b3919,0x2,
0x2b3f67d9,0xc01ccb1e,0x5311dcc8,0xdb9fdd9a,0x9118031e,0x0,
0x9a5c0d6e,0x4e99152f,0xaf853232,0x8db0dccc,0xef0f58d7,0x5,
0x6db63148,0xefdd7e0a,0xcc819e67,0x56a979bc,0x8d1169b4,0x3,
0x8670b917,0x3d61a2ac,0x6ed8588a,0x5cc94655,0x8096413e,0x2,
0xd8715f72,0xc2ce06e6,0xd50c5c77,0x1553a69b,0x8a20fadc,0x2,
0x9dd077b2,0xb2978893,0x7aa617bb,0xadbac172,0xf57da9a2,0x1,
0x6800bbe2,0x837ad74e,0xdac7cd95,0x1082c382,0xb5ec04b2,0x0,
0x43835328,0xa986d58b,0x8d7f7c4e,0xfd642a8d,0x6d4462d4,0x3,
0xf19901e9,0x60993930,0x67c98e9b,0x1ab9c90d,0x5d7f4593,0x6,
0x39e10752,0xde366730,0xa867db73,0x5bcb53b5,0x6b5e56c0,0x3,
0xaf59dcaa,0x8bdbf9ff,0x2221c861,0x52b45c1a,0x221a9b1f,0x6};
#define WORDS 6 /* Number of words per big variable 6*32 > 163 */
/* Note that in a real application a source of real random numbers would be required, to
replace those generated by MIRACL's internal pseudo-random generator "bigbits"
Alternatively from a truly random and unguessable seed, use MIRACL's strong random
number generator */
/* Elliptic Curve Diffie-Hellman, using point compression to minimize bandwidth,
and precomputation to speed up off-line calculation */
int main()
{
int promptr;
epoint *PA,*PB;
big A,B,a,b,q,pa,pb,key,x,y;
ebrick2 binst;
miracl instance; /* create miracl workspace on the stack */
/* Specify base 16 here so that HEX can be read in directly without a base-change */
miracl *mip=mirsys(&instance,WORDS*HEXDIGS,16); /* size of bigs is fixed */
char mem_big[MR_BIG_RESERVE(9)]; /* we need 9 bigs... */
char mem_ecp[MR_ECP_RESERVE(2)]; /* ..and two elliptic curve points */
memset(mem_big, 0, MR_BIG_RESERVE(9)); /* clear the memory */
memset(mem_ecp, 0, MR_ECP_RESERVE(2));
A=mirvar_mem(mip, mem_big, 0); /* Initialise big numbers */
B=mirvar_mem(mip, mem_big, 1);
pa=mirvar_mem(mip, mem_big, 2);
pb=mirvar_mem(mip, mem_big, 3);
key=mirvar_mem(mip, mem_big, 4);
x=mirvar_mem(mip, mem_big, 5);
y=mirvar_mem(mip, mem_big, 6);
a=mirvar_mem(mip, mem_big, 7);
b=mirvar_mem(mip, mem_big, 8);
PA=epoint_init_mem(mip, mem_ecp, 0); /* initialise Elliptic Curve points */
PB=epoint_init_mem(mip, mem_ecp, 1);
irand(mip, 3L); /* change parameter for different random numbers */
promptr=0;
init_big_from_rom(B,WORDS,rom,WORDS*4,&promptr); /* Read in curve parameter B from ROM */
/* don't need q or G(x,y) (we have precomputed table from it) */
convert(mip,1,A); /* set A=1 */
/* Create precomputation instance from precomputed table in ROM */
ebrick2_init(&binst,prom,A,B,CURVE_M,CURVE_A,CURVE_B,CURVE_C,WINDOW,CURVE_M);
/* offline calculations */
bigbits(mip,CURVE_M,a); /* A's random number */
mul2_brick(mip,&binst,a,pa,pa); /* a*G =(pa,ya) */
bigbits(mip,CURVE_M,b); /* B's random number */
mul2_brick(mip,&binst,b,pb,pb); /* b*G =(pb,yb) */
/* Swap X values */
/* online calculations */
ecurve2_init(mip,CURVE_M,CURVE_A,CURVE_B,CURVE_C,A,B,FALSE,MR_PROJECTIVE);
epoint2_set(mip,pb,pb,0,PB); /* decompress PB */
ecurve2_mult(mip,a,PB,PB);
epoint2_get(mip,PB,key,key);
/* since internal base is HEX, can use otnum instead of cotnum - avoiding a base change */
#ifndef MR_NO_STANDARD_IO
printf("Alice's Key= ");
otnum(mip,key,stdout);
#endif
epoint2_set(mip,pa,pa,0,PB); /* decompress PA */
ecurve2_mult(mip,b,PB,PB);
epoint2_get(mip,PB,key,key);
#ifndef MR_NO_STANDARD_IO
printf("Bob's Key= ");
otnum(mip,key,stdout);
#endif
/* clear the memory */
memset(mem_big, 0, MR_BIG_RESERVE(9));
memset(mem_ecp, 0, MR_ECP_RESERVE(2));
return 0;
}