/* Example Elliptic Curve Diffie-Hellman program for 8-bit constrained environments. Uses point compression. Stack-only memory allocation Use with this mirdef.h header (for a PC using MS C) #define MR_LITTLE_ENDIAN #define MIRACL 8 #define mr_utype char #define MR_IBITS 32 #define MR_LBITS 32 #define mr_unsign32 unsigned int #define mr_dltype short #define MR_STATIC 20 #define MR_ALWAYS_BINARY #define MR_NOASM #define MR_STRIPPED_DOWN #define MR_GENERIC_MT #define MAXBASE ((mr_small)1<<(MIRACL-1)) #define MR_COMBA 20 #define MR_SPECIAL #define MR_PSEUDO_MERSENNE #define MR_BITSINCHAR 8 #define MR_SMALL_EWINDOW #define MR_NO_ECC_MULTIADD #define MR_NO_LAZY_REDUCTION #define MR_SIMPLE_BASE #define MR_SIMPLE_IO Build the library from these modules (Example using MS C compiler) mex 20 c mrcomba rem In a real 8-bit setting, a suitable assembly language .mcs file would be used. Here we use C. 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 mrcurve.c cl /c /O2 /W3 mrsroot.c cl /c /O2 /W3 mrjack.c cl /c /O2 /W3 mrlucas.c cl /c /O2 /W3 mrarth2.c cl /c /O2 /W3 mrmonty.c cl /c /O2 /W3 mrcomba.c cl /c /O2 /W3 mrxgcd.c cl /c /O2 /W3 mrebrick.c rem rem Create library 'miracl.lib' del miracl.lib lib /OUT:miracl.lib mrio1.obj mrmonty.obj mrcomba.obj mrxgcd.obj lib /OUT:miracl.lib miracl.lib mrbits.obj mrarth2.obj mrlucas.obj mrjack.obj lib /OUT:miracl.lib miracl.lib mrarth0.obj mrarth1.obj mrcore.obj mrebrick.obj lib /OUT:miracl.lib miracl.lib mrcurve.obj mrsroot.obj del mr*.obj rem Create the program cl /O2 ecdhp8.c miracl.lib For Atmel AVR (atmega128) use #define MR_LITTLE_ENDIAN #define MIRACL 8 #define mr_utype char #define MR_IBITS 16 #define MR_LBITS 32 #define mr_unsign32 unsigned long #define mr_dltype int #define mr_qltype long #define MR_STATIC 20 #define MR_ALWAYS_BINARY #define MR_STRIPPED_DOWN #define MR_GENERIC_MT #define MAXBASE ((mr_small)1<<(MIRACL-1)) #define MR_COMBA 20 #define MR_SPECIAL #define MR_PSEUDO_MERSENNE #define MR_NOASM #define MR_BITSINCHAR 8 #define MR_NO_STANDARD_IO #define MR_NO_FILE_IO #define MR_NO_LAZY_REDUCTION #define MR_NO_ECC_MULTIADD #define MR_SIMPLE_BASE #define MR_SIMPLE_IO #define MR_SMALL_EWINDOW #define MR_AVR Note this last line is added manually - it will not be added by config and execute mex 20 avr4 mrcomba Note that reading data from program memory (NVM) is a little complex on the AVR! */ #include #include #include "miracl.h" /* !!!!!! THIS CODE AND THESE ROMS ARE NOW CREATED AUTOMATICALLY USING THE ROMAKER.C APPLICATION !!!!!!!! */ /* !!!!!! READ COMMENTS IN ROMAKER.C !!!!!! */ #define HEXDIGS (MIRACL/4) #define CURVE_BITS 160 /* Pseudo Mersenne 160 bit elliptic curve Y^2=X^3-3X+383 modulo 2^160-57 Here is stored P, B, the group order q, and the generator G(x,y) */ #ifdef MR_AVR __attribute__((__progmem__)) #endif static const mr_small rom[]= { 0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x7F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x25,0x32,0x7F,0x71,0x4B,0x4F,0xA0,0x01,0x3F,0x0E,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xf1,0x66,0x56,0xb7,0xee,0xbf,0x27,0xd0,0x4a,0xd0,0xb7,0x9,0x20,0x4e,0x59,0xed,0x5e,0xdc,0x8a,0xa, 0xda,0xc9,0x45,0x55,0xcc,0x6c,0x1c,0x11,0x9f,0x38,0x4d,0xac,0xd3,0x43,0x76,0xaf,0x5c,0x2d,0xfb,0x20}; #define WINDOW 4 /* 16 precomputed points based on fixed generator G(x,y) */ /* (created using romaker.c program with window size of 4) */ /* These values are only correct if MR_SPECIAL is defined! */ #ifdef MR_AVR __attribute__((__progmem__)) #endif static const mr_small prom[]= { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0xf1,0x66,0x56,0xb7,0xee,0xbf,0x27,0xd0,0x4a,0xd0,0xb7,0x9,0x20,0x4e,0x59,0xed,0x5e,0xdc,0x8a,0xa, 0xda,0xc9,0x45,0x55,0xcc,0x6c,0x1c,0x11,0x9f,0x38,0x4d,0xac,0xd3,0x43,0x76,0xaf,0x5c,0x2d,0xfb,0x20, 0xa,0xf8,0xdc,0xe5,0x96,0x7b,0xa2,0xad,0x89,0xa7,0xf2,0x19,0xfe,0xd6,0xcb,0xa0,0x91,0x44,0xaf,0xc6, 0x35,0xee,0xc1,0xa4,0x76,0xbe,0xda,0x91,0x5c,0xa3,0x6f,0xd9,0x24,0xe8,0x41,0x4f,0xe7,0x0,0xa,0x67, 0x16,0x9d,0xb1,0x30,0x2d,0xfa,0x9a,0x47,0x30,0x39,0x82,0xbb,0x39,0x7e,0x78,0x9e,0x1d,0xc9,0xa5,0x31, 0x64,0xe3,0x3,0x9b,0x4f,0xde,0x51,0x3f,0xb5,0x2,0x9f,0x68,0xe,0x65,0x3a,0x2f,0xae,0x4a,0xe9,0x79, 0xbf,0x66,0x86,0x3f,0xa0,0x5d,0x7f,0xc7,0x55,0x27,0x85,0x75,0xaa,0x9f,0x58,0x97,0x1f,0xec,0xe6,0xab, 0x92,0x36,0x32,0xf7,0x73,0x20,0x9d,0xdf,0x78,0x84,0x29,0x6d,0x3f,0x45,0x92,0xe7,0xd0,0x2d,0x64,0x2e, 0x62,0xd4,0x5d,0x1,0xe0,0x73,0x26,0xca,0xaa,0xcb,0xe7,0x87,0xf5,0xdd,0xa4,0xfe,0xd1,0xc7,0xbf,0xc7, 0x75,0x18,0x47,0xea,0x19,0xcb,0x4,0xd9,0x99,0x4f,0xc5,0x8b,0x57,0xf6,0xc0,0xe,0x11,0xaf,0x99,0x84, 0xdc,0x3b,0x49,0x31,0xb,0x77,0x55,0xdc,0x97,0xaa,0x56,0x7c,0x35,0x70,0x27,0x2c,0xd7,0xb5,0xee,0xc8, 0x4d,0x17,0x43,0xfe,0x80,0x8f,0x47,0x30,0xc2,0x83,0x91,0x94,0x17,0x65,0xa,0xfd,0x28,0xa5,0x4a,0x32, 0xb2,0x76,0xef,0xb8,0x49,0xdb,0xa,0xb0,0xb6,0x1a,0x5f,0xef,0x47,0x62,0x9f,0x37,0x7f,0xc,0xc,0x98, 0xe1,0x34,0x68,0x6b,0x46,0xe1,0x7,0x6c,0x4f,0x82,0xba,0x5d,0xf9,0xea,0xeb,0x69,0xa9,0xc2,0xa,0xa, 0x9e,0x9c,0xda,0xb0,0xfa,0xec,0x83,0xd1,0x38,0xc7,0x51,0x78,0x9d,0xe6,0xd4,0x5,0x83,0xde,0x56,0x1e, 0xf9,0x58,0xce,0x14,0x79,0xc7,0x63,0xa5,0x9b,0x10,0xf5,0x31,0x26,0x9c,0x1c,0x8b,0xba,0x7b,0x2b,0xcc, 0xdc,0x70,0xf7,0xc7,0xb5,0x3a,0xf0,0xc8,0x7d,0x5f,0x27,0xc1,0x4f,0x7b,0x26,0x84,0x8d,0xc4,0x88,0x9d, 0x7d,0x91,0xee,0x3e,0x20,0xc8,0xaf,0x22,0x5,0x47,0x58,0x4c,0x83,0xc6,0xae,0x76,0x6e,0x43,0x4b,0xd4, 0x54,0xf8,0xdf,0xa2,0xb9,0x4f,0xf5,0x83,0xfd,0x8e,0xbd,0xd7,0xf8,0xf0,0x4a,0xac,0xfa,0x13,0xa7,0xd0, 0xf3,0x25,0x61,0x4f,0x6b,0xec,0x13,0xdf,0xe1,0x4d,0x35,0x7e,0xba,0xf4,0xd9,0xa3,0xc,0x6e,0x82,0xb2, 0xf9,0xf4,0xf1,0x6d,0xce,0x72,0x63,0x7c,0x81,0x4b,0xaf,0x42,0xd8,0x85,0xa9,0xab,0xea,0xc9,0x1d,0x53, 0xb2,0xce,0xf9,0xd5,0x41,0x72,0xc8,0x5a,0x8f,0xc,0x75,0xbc,0xa9,0xf7,0x93,0xe5,0x6e,0xbe,0x76,0xd2, 0x6f,0x54,0xc9,0x15,0x86,0x48,0xe6,0x99,0xdc,0xcc,0x75,0x1a,0xfd,0xd6,0xd0,0x8c,0xcd,0x8,0xa7,0x39, 0xd0,0x64,0x2d,0xc,0xf3,0xa2,0xda,0x5d,0x96,0x76,0xf4,0x31,0x86,0xa,0x74,0xe7,0x6,0x60,0x29,0xb2, 0xbb,0xde,0x8,0x56,0x9f,0x8b,0x3f,0xff,0x30,0x4b,0xdc,0x32,0x4c,0x8f,0xb,0x63,0xd5,0x47,0x3f,0xb, 0xda,0x1c,0x77,0x84,0x5b,0x9d,0xaa,0x2f,0x77,0x6f,0xe8,0x1d,0x4e,0x69,0x6,0x8f,0x3d,0x7c,0xaf,0x7, 0xa1,0x42,0xae,0x2,0x24,0xa3,0x53,0x31,0x1f,0xe6,0x43,0x56,0x21,0x70,0x6e,0x1f,0x32,0xb3,0x17,0xe4, 0x51,0x4a,0xc0,0xd1,0xd1,0xb7,0xee,0xd6,0xc6,0xa8,0x3b,0x9a,0xe2,0xb8,0x11,0x8c,0x0,0xae,0x9b,0xdf, 0x3,0xbc,0x2c,0x78,0x5f,0xcf,0x24,0xba,0x7f,0x60,0x9,0x4c,0x8c,0x86,0xdd,0x11,0xfe,0x3f,0xe1,0xf5, 0xa0,0xb0,0x30,0xb6,0xb7,0x80,0xd8,0xb4,0x6a,0xbc,0x2e,0x43,0xaa,0x3b,0x4,0x28,0x13,0xef,0xa1,0x47}; #define WORDS 20 /* Number of words per big variable 20*8 = 160 */ /* 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,p,a,b,pa,pb,key,x,y; ebrick 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(10)]; /* we need 10 bigs... */ char mem_ecp[MR_ECP_RESERVE(2)]; /* ..and two elliptic curve points */ memset(mem_big, 0, MR_BIG_RESERVE(10)); /* 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); p=mirvar_mem(mip, mem_big, 9); 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(p,WORDS,rom,WORDS*5,&promptr); /* Read in prime modulus p from ROM */ init_big_from_rom(B,WORDS,rom,WORDS*5,&promptr); /* Read in curve parameter B from ROM */ /* don't need q or G(x,y) (we have precomputed table from it) */ convert(mip,-3,A); /* set A=-3 */ /* Create precomputation instance from precomputed table in ROM */ ebrick_init(&binst,prom,A,B,p,WINDOW,CURVE_BITS); /* offline calculations */ bigbits(mip,CURVE_BITS,a); /* A's random number */ mul_brick(mip,&binst,a,pa,pa); /* a*G =(pa,ya) */ bigbits(mip,CURVE_BITS,b); /* B's random number */ mul_brick(mip,&binst,b,pb,pb); /* b*G =(pb,yb) */ /* swap X values of point */ /* online calculations */ ecurve_init(mip,A,B,p,MR_PROJECTIVE); epoint_set(mip,pb,pb,0,PB); /* decompress PB */ ecurve_mult(mip,a,PB,PB); epoint_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 epoint_set(mip,pa,pa,0,PB); /* decompress PA */ ecurve_mult(mip,b,PB,PB); epoint_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(10)); memset(mem_ecp, 0, MR_ECP_RESERVE(2)); return 0; }