|
|
View previous topic :: View next topic |
Author |
Message |
rpweis
Joined: 19 Jul 2005 Posts: 3
|
MD5 Calculation with PIC16F877A |
Posted: Tue Jul 19, 2005 2:47 pm |
|
|
Hello,
I was trying to write an MD5 routine using the MD5 specification (rfc1321) and I ran out of ROM. Has anyone written a simpler version or done this another way? Basically I have to produce an MD5 of the contents of program memory (all of it) on request at any time for security purposes and I'm trying to do it within the pic as opposed to having dedicated external hardware. As far as an external implementation goes,
dsPIC with microchips encryption library looks like it would be a good approach. Anyone have any experience with dedicated security processors (usually seen in the secure networking market)?
Thanks,
Rob |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Wed Jul 20, 2005 7:37 am |
|
|
Do you have the *=16 in your code. Try and recompile with this in.
Code: | #include <16f877.h>
#device *=16
|
|
|
|
rpweis
Joined: 19 Jul 2005 Posts: 3
|
|
Posted: Wed Jul 20, 2005 9:04 am |
|
|
Yes I do have that in my code. I used reference parameters and the compiler directive "#separate" and all the other tricks I know of to try and make it fit. The compiler is not actually out of ROM, just doesn't have a block big enough left.
-Rob |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Wed Jul 20, 2005 10:27 am |
|
|
In your/my tricks, I will sometimes, "TELL" the compiler where the BIG block should go, then let it fill in the little spots. Can you post the code?
Code: |
#include <16F877.h>
#device *=16
#use delay(clock=16000000)
#fuses HS,NOWDT,NOLVP,
#use rs232(baud=19200,xmit=PIN_C4,INVERT,stream=DEBUG) // STDERR(same as DEBUG)
#case
#zero_ram
#RESERVE 0x110:0x17F
int8 buffer[112];//bigest size of block in 16F877 16+80+16=112
#BYTE buffer=0x110
//======================= Main ==============================
void main(void)
{
int8 i;
fprintf(DEBUG,"Starting\n\r");
for (i=0;i<112;i++)
{
buffer[i]=i;
fprintf(DEBUG,"%u\n\r",buffer[i]);
}
while(1)
{
}
}
|
|
|
|
rpweis
Joined: 19 Jul 2005 Posts: 3
|
|
Posted: Wed Jul 20, 2005 11:32 am |
|
|
Ok, here's my code. It's a little long b/c the include wasn't getting along earlier, probably works now but it doesn't really matter.
Code: |
#device PIC16F877A *=16
#fuses HS,NOWDT,NOPUT,NODEBUG,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
typedef int byte;
#include <stdio.h>
#include <math.h>
#use STANDARD_IO(A)
#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)
#use delay(clock=20000000)
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_A5 45
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58
#define PIN_C3 59
#define PIN_C4 60
#define PIN_C5 61
#define PIN_C6 62
#define PIN_C7 63
#define PIN_D0 64
#define PIN_D1 65
#define PIN_D2 66
#define PIN_D3 67
#define PIN_D4 68
#define PIN_D5 69
#define PIN_D6 70
#define PIN_D7 71
#define PIN_E0 72
#define PIN_E1 73
#define PIN_E2 74
#BIT RCIF = 0x0C.5
////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF 0
////////////////////////////////////////////////////////////////// PSP
// PSP Functions: SETUP_PSP, PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
// PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PSP Variables: PSP_DATA
// Constants used in SETUP_PSP() are:
#define PSP_ENABLED 0x10
#define PSP_DISABLED 0
////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE - Turn UART on
#define UART_ADDRESS 2
#define UART_DATA 4
////////////////////////////////////////////////////////////////// COMP
// Comparator Variables: C1OUT, C2OUT
// Constants used in setup_comparators() are:
#define A0_A3_A1_A3 0xfff04
#define A0_A3_A1_A2_OUT_ON_A4_A5 0xfcf03
#define A0_A3_A1_A3_OUT_ON_A4_A5 0xbcf05
#define NC_NC_NC_NC 0x0ff07
#define A0_A3_A1_A2 0xfff02
#define A0_A3_NC_NC_OUT_ON_A4 0x9ef01
#define A0_VR_A1_VR 0x3ff06
#define A3_VR_A2_VR 0xcff0e
#bit C1OUT = 0x9c.6
#bit C2OUT = 0x9c.7
////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER0(),
// SET_TIMER0() or SET_RTCC(),
// GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER0() are:
#define RTCC_INTERNAL 0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48
#define RTCC_DIV_1 8
#define RTCC_DIV_2 0
#define RTCC_DIV_4 1
#define RTCC_DIV_8 2
#define RTCC_DIV_16 3
#define RTCC_DIV_32 4
#define RTCC_DIV_64 5
#define RTCC_DIV_128 6
#define RTCC_DIV_256 7
#define RTCC_8_BIT 0
// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:
////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
// RESTART_WDT()
//
#define WDT_18MS 8
#define WDT_36MS 9
#define WDT_72MS 10
#define WDT_144MS 11
#define WDT_288MS 12
#define WDT_576MS 13
#define WDT_1152MS 14
#define WDT_2304MS 15
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
// (or (via |) together constants from each group)
#define T1_DISABLED 0
#define T1_INTERNAL 0x85
#define T1_EXTERNAL 0x87
#define T1_EXTERNAL_SYNC 0x83
#define T1_CLK_OUT 8
#define T1_DIV_BY_1 0
#define T1_DIV_BY_2 0x10
#define T1_DIV_BY_4 0x20
#define T1_DIV_BY_8 0x30
////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED 0
#define T2_DIV_BY_1 4
#define T2_DIV_BY_4 5
#define T2_DIV_BY_16 6
////////////////////////////////////////////////////////////////// VREF
// Constants used in setup_vref() are:
#define VREF_LOW 0xa0
#define VREF_HIGH 0x80
#define VREF_A2 0x40
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 0x86 // None
#define ALL_ANALOG 0x80 // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd
#define ANALOG_RA3_REF 0x81 // A0 A1 A2 A5 E0 E1 E2 Ref=A3
#define A_ANALOG 0x82 // A0 A1 A2 A3 A5 Ref=Vdd
#define A_ANALOG_RA3_REF 0x83 // A0 A1 A2 A5 Ref=A3
#define RA0_RA1_RA3_ANALOG 0x84 // A0 A1 A3 Ref=Vdd
#define RA0_RA1_ANALOG_RA3_REF 0x85 // A0 A1 Ref=A3
#define ANALOG_RA3_RA2_REF 0x88 // A0 A1 A5 E0 E1 E2 Ref=A2,A3
#define ANALOG_NOT_RE1_RE2 0x89 // A0 A1 A2 A3 A5 E0 Ref=Vdd
#define ANALOG_NOT_RE1_RE2_REF_RA3 0x8A // A0 A1 A2 A5 E0 Ref=A3
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2 0x8B // A0 A1 A5 E0 Ref=A2,A3
#define A_ANALOG_RA3_RA2_REF 0x8C // A0 A1 A5 Ref=A2,A3
#define RA0_RA1_ANALOG_RA3_RA2_REF 0x8D // A0 A1 Ref=A2,A3
#define RA0_ANALOG 0x8E // A0
#define RA0_ANALOG_RA3_RA2_REF 0x8F // A0 Ref=A2,A3
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 1
#define ADC_CLOCK_DIV_8 0x41
#define ADC_CLOCK_DIV_32 0x81
#define ADC_CLOCK_INTERNAL 0xc1 // Internal 2-6us
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6
////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
// EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H 0x40
#define H_TO_L 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL 0x0BC0
#define INT_RTCC 0x0B20
#define INT_RB 0x0B08
#define INT_EXT 0x0B10
#define INT_AD 0x8C40
#define INT_TBE 0x8C10
#define INT_RDA 0x8C20
#define INT_TIMER1 0x8C01
#define INT_TIMER2 0x8C02
#define INT_CCP1 0x8C04
#define INT_CCP2 0x8D01
#define INT_SSP 0x8C08
#define INT_PSP 0x8C80
#define INT_BUSCOL 0x8D08
#define INT_EEPROM 0x8D10
#define INT_TIMER0 0x0B20
#define INT_COMP 0x8D40
//#BIT RCIF = 0x0C.5
//#define vmax 7800
//#define accel 160
//#define decel 240
#define md5length 115200
int32 workmssg[16];
#use rs232(baud=9600, xmit=PIN_C6, RCV=PIN_C7, PARITY=E, ERRORS)
/*
int32 f(int32 x,int32 y, int32 z);
int32 g(int32 x,int32 y, int32 z);
int32 h(int32 x,int32 y, int32 z);
int32 i(int32 x,int32 y, int32 z);
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
*/
#separate
int32 f(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(y))|((~x)&(z)));
return(res);
}
#separate
int32 g(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(z))|((y)&(~z)));
return(res);
}
#separate
int32 h(int32 x,int32 y, int32 z)
{
int32 res;
res = ((x)^(y)^(z));
return(res);
}
#separate
int32 i(int32 x,int32 y, int32 z)
{
int32 res;
res = ((y)^((x)|(~z)));
return(res);
}
#separate
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 1 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b+(a+f(b,c,d)+workmssg[k]+(4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 2 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a+g(b,c,d) + workmssg[k] + (4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 3 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + h(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 4 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + i(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
void round1a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]*/
a = ff(a,b,c,d,0,7,1);
d = ff(d,a,b,c,1,12,2);
c = ff(c,d,a,b,2,17,3);
b = ff(b,c,d,a,3,22,4);
}
#separate
void round1b(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,4,7,5);
d = ff(d,a,b,c,5,12,6);
c = ff(c,d,a,b,6,17,7);
b = ff(b,c,d,a,7,22,8);
}
#separate
void round1c(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,8,7,9);
d = ff(d,a,b,c,9,12,10);
c = ff(c,d,a,b,10,17,11);
b = ff(b,c,d,a,11,22,12);
}
#separate
void round1d(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,12,7,13);
d = ff(d,a,b,c,13,12,14);
c = ff(c,d,a,b,14,17,15);
b = ff(b,c,d,a,15,22,16);
}
#separate
void round2a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]*/
a = gg(a,b,c,d,1,5,17);
d = gg(d,a,b,c,6,9,18);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,0,20,20);
}
#separate
void round2b(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,5,5,21);
d = gg(d,a,b,c,10,9,22);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,4,20,24);
}
#separate
void round2c(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,9,5,25);
d = gg(d,a,b,c,14,9,26);
c = gg(c,d,a,b,3,14,27);
b = gg(b,c,d,a,8,20,28);
}
#separate
void round2d(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,13,5,29);
d = gg(d,a,b,c,2,9,30);
c = gg(c,d,a,b,7,14,31);
b = gg(b,c,d,a,12,20,32);
}
#separate
void round3a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]*/
a = hh(a,b,c,d,5,4,33);
d = hh(d,a,b,c,8,11,34);
c = hh(c,d,a,b,11,16,35);
b = hh(b,c,d,a,14,23,36);
}
#separate
void round3b(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,1,4,37);
d = hh(d,a,b,c,4,11,38);
c = hh(c,d,a,b,7,16,39);
b = hh(b,c,d,a,10,23,40);
}
#separate
void round3c(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,13,4,41);
d = hh(d,a,b,c,0,11,42);
c = hh(c,d,a,b,3,16,43);
b = hh(b,c,d,a,6,23,44);
}
#separate
void round3d(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,9,4,45);
d = hh(d,a,b,c,12,11,46);
c = hh(c,d,a,b,15,16,47);
b = hh(b,c,d,a,2,23,48);
}
#separate
void round4a(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4b(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4c(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4d(int32& a,int32& b,int32& c,int32& d)
{
}
void main()
{
int i,j;
int32 extmssg[16],aa,bb,cc,dd,a,b,c,d;
for(i=0;i<16;i++)
{
extmssg[i]=0;
}
extmssg[0] = 1;
extmssg[14] = md5length;
a = 0x01234567;
b = 0x89abcdef;
c = 0xfedcba98;
d = 0x76543210;
for(i=0;i<=((md5length/32)/16-2);i++) //-2 b/c of goofy extmssg idea
{
for(j=0;j<=15;j++)
{
workmssg[j] = read_program_eeprom((i*16)+j);
}
aa=a;
bb=b;
cc=c;
dd=d;
round1a(a,b,c,d);
round1b(a,b,c,d);
round1c(a,b,c,d);
round1d(a,b,c,d);
round2a(a,b,c,d);
round2b(a,b,c,d);
round2c(a,b,c,d);
round2d(a,b,c,d);
round3a(a,b,c,d);
round3b(a,b,c,d);
round3c(a,b,c,d);
round3d(a,b,c,d);
round4a(a,b,c,d);
round4b(a,b,c,d);
round4c(a,b,c,d);
round4d(a,b,c,d);
a += aa;
b += bb;
c += cc;
d += dd;
}
//md5 done, result is DCBA
}
|
The reason there are so many functions is because I was trying to make the smallest blocks possible for the compiler to place. I made them all separate to force it to call instead of place it inline. The 32 bit math is definately killer on the RAM, but I thought that a PIC should be able to calculate an MD5 hash. The math isn't that bad, just big numbers. Any thoughts?
Thanks,
Rob |
|
|
rpweis
Joined: 19 Jul 2005 Posts: 3
|
|
Posted: Wed Jul 20, 2005 11:32 am |
|
|
Ok, here's my code. It's a little long b/c the include wasn't getting along earlier, probably works now but it doesn't really matter.
Code: |
#device PIC16F877A *=16
#fuses HS,NOWDT,NOPUT,NODEBUG,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
typedef int byte;
#include <stdio.h>
#include <math.h>
#use STANDARD_IO(A)
#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)
#use delay(clock=20000000)
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_A5 45
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58
#define PIN_C3 59
#define PIN_C4 60
#define PIN_C5 61
#define PIN_C6 62
#define PIN_C7 63
#define PIN_D0 64
#define PIN_D1 65
#define PIN_D2 66
#define PIN_D3 67
#define PIN_D4 68
#define PIN_D5 69
#define PIN_D6 70
#define PIN_D7 71
#define PIN_E0 72
#define PIN_E1 73
#define PIN_E2 74
#BIT RCIF = 0x0C.5
////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF 0
////////////////////////////////////////////////////////////////// PSP
// PSP Functions: SETUP_PSP, PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
// PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PSP Variables: PSP_DATA
// Constants used in SETUP_PSP() are:
#define PSP_ENABLED 0x10
#define PSP_DISABLED 0
////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE - Turn UART on
#define UART_ADDRESS 2
#define UART_DATA 4
////////////////////////////////////////////////////////////////// COMP
// Comparator Variables: C1OUT, C2OUT
// Constants used in setup_comparators() are:
#define A0_A3_A1_A3 0xfff04
#define A0_A3_A1_A2_OUT_ON_A4_A5 0xfcf03
#define A0_A3_A1_A3_OUT_ON_A4_A5 0xbcf05
#define NC_NC_NC_NC 0x0ff07
#define A0_A3_A1_A2 0xfff02
#define A0_A3_NC_NC_OUT_ON_A4 0x9ef01
#define A0_VR_A1_VR 0x3ff06
#define A3_VR_A2_VR 0xcff0e
#bit C1OUT = 0x9c.6
#bit C2OUT = 0x9c.7
////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER0(),
// SET_TIMER0() or SET_RTCC(),
// GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER0() are:
#define RTCC_INTERNAL 0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48
#define RTCC_DIV_1 8
#define RTCC_DIV_2 0
#define RTCC_DIV_4 1
#define RTCC_DIV_8 2
#define RTCC_DIV_16 3
#define RTCC_DIV_32 4
#define RTCC_DIV_64 5
#define RTCC_DIV_128 6
#define RTCC_DIV_256 7
#define RTCC_8_BIT 0
// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:
////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
// RESTART_WDT()
//
#define WDT_18MS 8
#define WDT_36MS 9
#define WDT_72MS 10
#define WDT_144MS 11
#define WDT_288MS 12
#define WDT_576MS 13
#define WDT_1152MS 14
#define WDT_2304MS 15
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
// (or (via |) together constants from each group)
#define T1_DISABLED 0
#define T1_INTERNAL 0x85
#define T1_EXTERNAL 0x87
#define T1_EXTERNAL_SYNC 0x83
#define T1_CLK_OUT 8
#define T1_DIV_BY_1 0
#define T1_DIV_BY_2 0x10
#define T1_DIV_BY_4 0x20
#define T1_DIV_BY_8 0x30
////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED 0
#define T2_DIV_BY_1 4
#define T2_DIV_BY_4 5
#define T2_DIV_BY_16 6
////////////////////////////////////////////////////////////////// VREF
// Constants used in setup_vref() are:
#define VREF_LOW 0xa0
#define VREF_HIGH 0x80
#define VREF_A2 0x40
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 0x86 // None
#define ALL_ANALOG 0x80 // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd
#define ANALOG_RA3_REF 0x81 // A0 A1 A2 A5 E0 E1 E2 Ref=A3
#define A_ANALOG 0x82 // A0 A1 A2 A3 A5 Ref=Vdd
#define A_ANALOG_RA3_REF 0x83 // A0 A1 A2 A5 Ref=A3
#define RA0_RA1_RA3_ANALOG 0x84 // A0 A1 A3 Ref=Vdd
#define RA0_RA1_ANALOG_RA3_REF 0x85 // A0 A1 Ref=A3
#define ANALOG_RA3_RA2_REF 0x88 // A0 A1 A5 E0 E1 E2 Ref=A2,A3
#define ANALOG_NOT_RE1_RE2 0x89 // A0 A1 A2 A3 A5 E0 Ref=Vdd
#define ANALOG_NOT_RE1_RE2_REF_RA3 0x8A // A0 A1 A2 A5 E0 Ref=A3
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2 0x8B // A0 A1 A5 E0 Ref=A2,A3
#define A_ANALOG_RA3_RA2_REF 0x8C // A0 A1 A5 Ref=A2,A3
#define RA0_RA1_ANALOG_RA3_RA2_REF 0x8D // A0 A1 Ref=A2,A3
#define RA0_ANALOG 0x8E // A0
#define RA0_ANALOG_RA3_RA2_REF 0x8F // A0 Ref=A2,A3
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 1
#define ADC_CLOCK_DIV_8 0x41
#define ADC_CLOCK_DIV_32 0x81
#define ADC_CLOCK_INTERNAL 0xc1 // Internal 2-6us
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6
////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
// EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H 0x40
#define H_TO_L 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL 0x0BC0
#define INT_RTCC 0x0B20
#define INT_RB 0x0B08
#define INT_EXT 0x0B10
#define INT_AD 0x8C40
#define INT_TBE 0x8C10
#define INT_RDA 0x8C20
#define INT_TIMER1 0x8C01
#define INT_TIMER2 0x8C02
#define INT_CCP1 0x8C04
#define INT_CCP2 0x8D01
#define INT_SSP 0x8C08
#define INT_PSP 0x8C80
#define INT_BUSCOL 0x8D08
#define INT_EEPROM 0x8D10
#define INT_TIMER0 0x0B20
#define INT_COMP 0x8D40
//#BIT RCIF = 0x0C.5
//#define vmax 7800
//#define accel 160
//#define decel 240
#define md5length 115200
int32 workmssg[16];
#use rs232(baud=9600, xmit=PIN_C6, RCV=PIN_C7, PARITY=E, ERRORS)
/*
int32 f(int32 x,int32 y, int32 z);
int32 g(int32 x,int32 y, int32 z);
int32 h(int32 x,int32 y, int32 z);
int32 i(int32 x,int32 y, int32 z);
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
*/
#separate
int32 f(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(y))|((~x)&(z)));
return(res);
}
#separate
int32 g(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(z))|((y)&(~z)));
return(res);
}
#separate
int32 h(int32 x,int32 y, int32 z)
{
int32 res;
res = ((x)^(y)^(z));
return(res);
}
#separate
int32 i(int32 x,int32 y, int32 z)
{
int32 res;
res = ((y)^((x)|(~z)));
return(res);
}
#separate
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 1 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b+(a+f(b,c,d)+workmssg[k]+(4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 2 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a+g(b,c,d) + workmssg[k] + (4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 3 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + h(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 4 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + i(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
void round1a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]*/
a = ff(a,b,c,d,0,7,1);
d = ff(d,a,b,c,1,12,2);
c = ff(c,d,a,b,2,17,3);
b = ff(b,c,d,a,3,22,4);
}
#separate
void round1b(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,4,7,5);
d = ff(d,a,b,c,5,12,6);
c = ff(c,d,a,b,6,17,7);
b = ff(b,c,d,a,7,22,8);
}
#separate
void round1c(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,8,7,9);
d = ff(d,a,b,c,9,12,10);
c = ff(c,d,a,b,10,17,11);
b = ff(b,c,d,a,11,22,12);
}
#separate
void round1d(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,12,7,13);
d = ff(d,a,b,c,13,12,14);
c = ff(c,d,a,b,14,17,15);
b = ff(b,c,d,a,15,22,16);
}
#separate
void round2a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]*/
a = gg(a,b,c,d,1,5,17);
d = gg(d,a,b,c,6,9,18);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,0,20,20);
}
#separate
void round2b(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,5,5,21);
d = gg(d,a,b,c,10,9,22);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,4,20,24);
}
#separate
void round2c(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,9,5,25);
d = gg(d,a,b,c,14,9,26);
c = gg(c,d,a,b,3,14,27);
b = gg(b,c,d,a,8,20,28);
}
#separate
void round2d(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,13,5,29);
d = gg(d,a,b,c,2,9,30);
c = gg(c,d,a,b,7,14,31);
b = gg(b,c,d,a,12,20,32);
}
#separate
void round3a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]*/
a = hh(a,b,c,d,5,4,33);
d = hh(d,a,b,c,8,11,34);
c = hh(c,d,a,b,11,16,35);
b = hh(b,c,d,a,14,23,36);
}
#separate
void round3b(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,1,4,37);
d = hh(d,a,b,c,4,11,38);
c = hh(c,d,a,b,7,16,39);
b = hh(b,c,d,a,10,23,40);
}
#separate
void round3c(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,13,4,41);
d = hh(d,a,b,c,0,11,42);
c = hh(c,d,a,b,3,16,43);
b = hh(b,c,d,a,6,23,44);
}
#separate
void round3d(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,9,4,45);
d = hh(d,a,b,c,12,11,46);
c = hh(c,d,a,b,15,16,47);
b = hh(b,c,d,a,2,23,48);
}
#separate
void round4a(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4b(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4c(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4d(int32& a,int32& b,int32& c,int32& d)
{
}
void main()
{
int i,j;
int32 extmssg[16],aa,bb,cc,dd,a,b,c,d;
for(i=0;i<16;i++)
{
extmssg[i]=0;
}
extmssg[0] = 1;
extmssg[14] = md5length;
a = 0x01234567;
b = 0x89abcdef;
c = 0xfedcba98;
d = 0x76543210;
for(i=0;i<=((md5length/32)/16-2);i++) //-2 b/c of goofy extmssg idea
{
for(j=0;j<=15;j++)
{
workmssg[j] = read_program_eeprom((i*16)+j);
}
aa=a;
bb=b;
cc=c;
dd=d;
round1a(a,b,c,d);
round1b(a,b,c,d);
round1c(a,b,c,d);
round1d(a,b,c,d);
round2a(a,b,c,d);
round2b(a,b,c,d);
round2c(a,b,c,d);
round2d(a,b,c,d);
round3a(a,b,c,d);
round3b(a,b,c,d);
round3c(a,b,c,d);
round3d(a,b,c,d);
round4a(a,b,c,d);
round4b(a,b,c,d);
round4c(a,b,c,d);
round4d(a,b,c,d);
a += aa;
b += bb;
c += cc;
d += dd;
}
//md5 done, result is DCBA
}
|
The reason there are so many functions is because I was trying to make the smallest blocks possible for the compiler to place. I made them all separate to force it to call instead of place it inline. The 32 bit math is definately killer on the RAM, but I thought that a PIC should be able to calculate an MD5 hash. The math isn't that bad, just big numbers. Any thoughts?
Thanks,
Rob |
|
|
rpweis
Joined: 19 Jul 2005 Posts: 3
|
|
Posted: Wed Jul 20, 2005 11:33 am |
|
|
Ok, here's my code. It's a little long b/c the include wasn't getting along earlier, probably works now but it doesn't really matter.
Code: |
#device PIC16F877A *=16
#fuses HS,NOWDT,NOPUT,NODEBUG,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
typedef int byte;
#include <stdio.h>
#include <math.h>
#use STANDARD_IO(A)
#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)
#use delay(clock=20000000)
#define PIN_A0 40
#define PIN_A1 41
#define PIN_A2 42
#define PIN_A3 43
#define PIN_A4 44
#define PIN_A5 45
#define PIN_B0 48
#define PIN_B1 49
#define PIN_B2 50
#define PIN_B3 51
#define PIN_B4 52
#define PIN_B5 53
#define PIN_B6 54
#define PIN_B7 55
#define PIN_C0 56
#define PIN_C1 57
#define PIN_C2 58
#define PIN_C3 59
#define PIN_C4 60
#define PIN_C5 61
#define PIN_C6 62
#define PIN_C7 63
#define PIN_D0 64
#define PIN_D1 65
#define PIN_D2 66
#define PIN_D3 67
#define PIN_D4 68
#define PIN_D5 69
#define PIN_D6 70
#define PIN_D7 71
#define PIN_E0 72
#define PIN_E1 73
#define PIN_E2 74
#BIT RCIF = 0x0C.5
////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF 0
////////////////////////////////////////////////////////////////// PSP
// PSP Functions: SETUP_PSP, PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
// PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PSP Variables: PSP_DATA
// Constants used in SETUP_PSP() are:
#define PSP_ENABLED 0x10
#define PSP_DISABLED 0
////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE - Turn UART on
#define UART_ADDRESS 2
#define UART_DATA 4
////////////////////////////////////////////////////////////////// COMP
// Comparator Variables: C1OUT, C2OUT
// Constants used in setup_comparators() are:
#define A0_A3_A1_A3 0xfff04
#define A0_A3_A1_A2_OUT_ON_A4_A5 0xfcf03
#define A0_A3_A1_A3_OUT_ON_A4_A5 0xbcf05
#define NC_NC_NC_NC 0x0ff07
#define A0_A3_A1_A2 0xfff02
#define A0_A3_NC_NC_OUT_ON_A4 0x9ef01
#define A0_VR_A1_VR 0x3ff06
#define A3_VR_A2_VR 0xcff0e
#bit C1OUT = 0x9c.6
#bit C2OUT = 0x9c.7
////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER0(),
// SET_TIMER0() or SET_RTCC(),
// GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER0() are:
#define RTCC_INTERNAL 0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48
#define RTCC_DIV_1 8
#define RTCC_DIV_2 0
#define RTCC_DIV_4 1
#define RTCC_DIV_8 2
#define RTCC_DIV_16 3
#define RTCC_DIV_32 4
#define RTCC_DIV_64 5
#define RTCC_DIV_128 6
#define RTCC_DIV_256 7
#define RTCC_8_BIT 0
// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:
////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
// RESTART_WDT()
//
#define WDT_18MS 8
#define WDT_36MS 9
#define WDT_72MS 10
#define WDT_144MS 11
#define WDT_288MS 12
#define WDT_576MS 13
#define WDT_1152MS 14
#define WDT_2304MS 15
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
// (or (via |) together constants from each group)
#define T1_DISABLED 0
#define T1_INTERNAL 0x85
#define T1_EXTERNAL 0x87
#define T1_EXTERNAL_SYNC 0x83
#define T1_CLK_OUT 8
#define T1_DIV_BY_1 0
#define T1_DIV_BY_2 0x10
#define T1_DIV_BY_4 0x20
#define T1_DIV_BY_8 0x30
////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED 0
#define T2_DIV_BY_1 4
#define T2_DIV_BY_4 5
#define T2_DIV_BY_16 6
////////////////////////////////////////////////////////////////// VREF
// Constants used in setup_vref() are:
#define VREF_LOW 0xa0
#define VREF_HIGH 0x80
#define VREF_A2 0x40
////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 0x86 // None
#define ALL_ANALOG 0x80 // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd
#define ANALOG_RA3_REF 0x81 // A0 A1 A2 A5 E0 E1 E2 Ref=A3
#define A_ANALOG 0x82 // A0 A1 A2 A3 A5 Ref=Vdd
#define A_ANALOG_RA3_REF 0x83 // A0 A1 A2 A5 Ref=A3
#define RA0_RA1_RA3_ANALOG 0x84 // A0 A1 A3 Ref=Vdd
#define RA0_RA1_ANALOG_RA3_REF 0x85 // A0 A1 Ref=A3
#define ANALOG_RA3_RA2_REF 0x88 // A0 A1 A5 E0 E1 E2 Ref=A2,A3
#define ANALOG_NOT_RE1_RE2 0x89 // A0 A1 A2 A3 A5 E0 Ref=Vdd
#define ANALOG_NOT_RE1_RE2_REF_RA3 0x8A // A0 A1 A2 A5 E0 Ref=A3
#define ANALOG_NOT_RE1_RE2_REF_RA3_RA2 0x8B // A0 A1 A5 E0 Ref=A2,A3
#define A_ANALOG_RA3_RA2_REF 0x8C // A0 A1 A5 Ref=A2,A3
#define RA0_RA1_ANALOG_RA3_RA2_REF 0x8D // A0 A1 Ref=A2,A3
#define RA0_ANALOG 0x8E // A0
#define RA0_ANALOG_RA3_RA2_REF 0x8F // A0 Ref=A2,A3
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 1
#define ADC_CLOCK_DIV_8 0x41
#define ADC_CLOCK_DIV_32 0x81
#define ADC_CLOCK_INTERNAL 0xc1 // Internal 2-6us
// Constants used in READ_ADC() are:
#define ADC_START_AND_READ 7 // This is the default if nothing is specified
#define ADC_START_ONLY 1
#define ADC_READ_ONLY 6
////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
// EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H 0x40
#define H_TO_L 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL 0x0BC0
#define INT_RTCC 0x0B20
#define INT_RB 0x0B08
#define INT_EXT 0x0B10
#define INT_AD 0x8C40
#define INT_TBE 0x8C10
#define INT_RDA 0x8C20
#define INT_TIMER1 0x8C01
#define INT_TIMER2 0x8C02
#define INT_CCP1 0x8C04
#define INT_CCP2 0x8D01
#define INT_SSP 0x8C08
#define INT_PSP 0x8C80
#define INT_BUSCOL 0x8D08
#define INT_EEPROM 0x8D10
#define INT_TIMER0 0x0B20
#define INT_COMP 0x8D40
//#BIT RCIF = 0x0C.5
//#define vmax 7800
//#define accel 160
//#define decel 240
#define md5length 115200
int32 workmssg[16];
#use rs232(baud=9600, xmit=PIN_C6, RCV=PIN_C7, PARITY=E, ERRORS)
/*
int32 f(int32 x,int32 y, int32 z);
int32 g(int32 x,int32 y, int32 z);
int32 h(int32 x,int32 y, int32 z);
int32 i(int32 x,int32 y, int32 z);
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
*/
#separate
int32 f(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(y))|((~x)&(z)));
return(res);
}
#separate
int32 g(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(z))|((y)&(~z)));
return(res);
}
#separate
int32 h(int32 x,int32 y, int32 z)
{
int32 res;
res = ((x)^(y)^(z));
return(res);
}
#separate
int32 i(int32 x,int32 y, int32 z)
{
int32 res;
res = ((y)^((x)|(~z)));
return(res);
}
#separate
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 1 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b+(a+f(b,c,d)+workmssg[k]+(4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 2 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a+g(b,c,d) + workmssg[k] + (4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 3 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + h(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 4 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + i(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
#separate
void round1a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]*/
a = ff(a,b,c,d,0,7,1);
d = ff(d,a,b,c,1,12,2);
c = ff(c,d,a,b,2,17,3);
b = ff(b,c,d,a,3,22,4);
}
#separate
void round1b(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,4,7,5);
d = ff(d,a,b,c,5,12,6);
c = ff(c,d,a,b,6,17,7);
b = ff(b,c,d,a,7,22,8);
}
#separate
void round1c(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,8,7,9);
d = ff(d,a,b,c,9,12,10);
c = ff(c,d,a,b,10,17,11);
b = ff(b,c,d,a,11,22,12);
}
#separate
void round1d(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,12,7,13);
d = ff(d,a,b,c,13,12,14);
c = ff(c,d,a,b,14,17,15);
b = ff(b,c,d,a,15,22,16);
}
#separate
void round2a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]*/
a = gg(a,b,c,d,1,5,17);
d = gg(d,a,b,c,6,9,18);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,0,20,20);
}
#separate
void round2b(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,5,5,21);
d = gg(d,a,b,c,10,9,22);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,4,20,24);
}
#separate
void round2c(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,9,5,25);
d = gg(d,a,b,c,14,9,26);
c = gg(c,d,a,b,3,14,27);
b = gg(b,c,d,a,8,20,28);
}
#separate
void round2d(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,13,5,29);
d = gg(d,a,b,c,2,9,30);
c = gg(c,d,a,b,7,14,31);
b = gg(b,c,d,a,12,20,32);
}
#separate
void round3a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]*/
a = hh(a,b,c,d,5,4,33);
d = hh(d,a,b,c,8,11,34);
c = hh(c,d,a,b,11,16,35);
b = hh(b,c,d,a,14,23,36);
}
#separate
void round3b(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,1,4,37);
d = hh(d,a,b,c,4,11,38);
c = hh(c,d,a,b,7,16,39);
b = hh(b,c,d,a,10,23,40);
}
#separate
void round3c(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,13,4,41);
d = hh(d,a,b,c,0,11,42);
c = hh(c,d,a,b,3,16,43);
b = hh(b,c,d,a,6,23,44);
}
#separate
void round3d(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,9,4,45);
d = hh(d,a,b,c,12,11,46);
c = hh(c,d,a,b,15,16,47);
b = hh(b,c,d,a,2,23,48);
}
#separate
void round4a(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4b(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4c(int32& a,int32& b,int32& c,int32& d)
{
}
#separate
void round4d(int32& a,int32& b,int32& c,int32& d)
{
}
void main()
{
int i,j;
int32 extmssg[16],aa,bb,cc,dd,a,b,c,d;
for(i=0;i<16;i++)
{
extmssg[i]=0;
}
extmssg[0] = 1;
extmssg[14] = md5length;
a = 0x01234567;
b = 0x89abcdef;
c = 0xfedcba98;
d = 0x76543210;
for(i=0;i<=((md5length/32)/16-2);i++) //-2 b/c of goofy extmssg idea
{
for(j=0;j<=15;j++)
{
workmssg[j] = read_program_eeprom((i*16)+j);
}
aa=a;
bb=b;
cc=c;
dd=d;
round1a(a,b,c,d);
round1b(a,b,c,d);
round1c(a,b,c,d);
round1d(a,b,c,d);
round2a(a,b,c,d);
round2b(a,b,c,d);
round2c(a,b,c,d);
round2d(a,b,c,d);
round3a(a,b,c,d);
round3b(a,b,c,d);
round3c(a,b,c,d);
round3d(a,b,c,d);
round4a(a,b,c,d);
round4b(a,b,c,d);
round4c(a,b,c,d);
round4d(a,b,c,d);
a += aa;
b += bb;
c += cc;
d += dd;
}
//md5 done, result is DCBA
}
|
The reason there are so many functions is because I was trying to make the smallest blocks possible for the compiler to place. I made them all separate to force it to call instead of place it inline. The 32 bit math is definately killer on the RAM, but I thought that a PIC should be able to calculate an MD5 hash. The math isn't that bad, just big numbers. Any thoughts?
Thanks,
Rob |
|
|
rpweis
Joined: 19 Jul 2005 Posts: 3
|
|
Posted: Wed Jul 20, 2005 11:34 am |
|
|
Sorry about the multiple posts, the page kept saying it couldn;t load, but apparently it did.
-Rob |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Jul 20, 2005 1:14 pm |
|
|
Since you were logged in when you posted, you can delete the extra posts. Just click the X in the box when you view the post(s). |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 20, 2005 1:24 pm |
|
|
You can only delete a post if it's the last one added to the thread.
Once someone replies to it, the little "X" box is no longer available.
But you can still edit your duplicate posts and delete the text in them. |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Wed Jul 20, 2005 3:51 pm |
|
|
I can't find a way to make your program fit in ROM.
The program is just too big.
When I comment out functions, I can leave in like 3 and it compiles.
at about 50% ram 50% rom.
Add another function call and it blows. ??? Anyone know why such a big jump.
Code: |
#include <16F877A.h>
#device *=16
#use delay(clock=6000000)
#fuses HS,NOWDT,NOLVP,PROTECT,PUT,BROWNOUT
#use rs232(baud=19200,xmit=PIN_E0,INVERT,stream=DEBUG) // STDERR(same as DEBUG)
#use rs232(baud=1200,errors,xmit=PIN_C6,rcv=PIN_C7,parity=e,enable=PIN_C5,bits=8,stream=CIM)
#include <stdio.h>
#include <math.h>
#use STANDARD_IO(A)
#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)
#BIT RCIF = 0x0C.5
#bit C1OUT = 0x9c.6
#bit C2OUT = 0x9c.7
#define md5length 115200
int32 workmssg[16];
//#use rs232(baud=9600, xmit=PIN_C6, RCV=PIN_C7, PARITY=E, ERRORS)
/*
int32 f(int32 x,int32 y, int32 z);
int32 g(int32 x,int32 y, int32 z);
int32 h(int32 x,int32 y, int32 z);
int32 i(int32 x,int32 y, int32 z);
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i);
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t);
*/
int32 f(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(y))|((~x)&(z)));
return(res);
}
int32 g(int32 x,int32 y, int32 z)
{
int32 res;
res = (((x)&(z))|((y)&(~z)));
return(res);
}
int32 h(int32 x,int32 y, int32 z)
{
int32 res;
res = ((x)^(y)^(z));
return(res);
}
int32 i(int32 x,int32 y, int32 z)
{
int32 res;
res = ((y)^((x)|(~z)));
return(res);
}
int32 ff(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 1 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b+(a+f(b,c,d)+workmssg[k]+(4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
int32 gg(int32 a,int32 b, int32 c, int32 d, int k, int s, int i) //round 2 function
{
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a+g(b,c,d) + workmssg[k] + (4294967296*abs(sin(i))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
int32 hh(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 3 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + h(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
int32 ii(int32 a,int32 b, int32 c, int32 d, int k, int s, int t) //round 4 function
{
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
int32 res;
res = b + (a + i(b,c,d) + workmssg[k] + (4294967296*abs(sin(t))));
res = (((res)<<(s))|((res)>>(32-(s)))); //rotate left
return(res);
}
void round1a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]*/
a = ff(a,b,c,d,0,7,1);
d = ff(d,a,b,c,1,12,2);
c = ff(c,d,a,b,2,17,3);
b = ff(b,c,d,a,3,22,4);
}
void round1b(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,4,7,5);
d = ff(d,a,b,c,5,12,6);
c = ff(c,d,a,b,6,17,7);
b = ff(b,c,d,a,7,22,8);
}
void round1c(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,8,7,9);
d = ff(d,a,b,c,9,12,10);
c = ff(c,d,a,b,10,17,11);
b = ff(b,c,d,a,11,22,12);
}
void round1d(int32& a,int32& b,int32& c,int32& d)
{
a = ff(a,b,c,d,12,7,13);
d = ff(d,a,b,c,13,12,14);
c = ff(c,d,a,b,14,17,15);
b = ff(b,c,d,a,15,22,16);
}
void round2a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]*/
a = gg(a,b,c,d,1,5,17);
d = gg(d,a,b,c,6,9,18);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,0,20,20);
}
void round2b(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,5,5,21);
d = gg(d,a,b,c,10,9,22);
c = gg(c,d,a,b,11,14,19);
b = gg(b,c,d,a,4,20,24);
}
void round2c(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,9,5,25);
d = gg(d,a,b,c,14,9,26);
c = gg(c,d,a,b,3,14,27);
b = gg(b,c,d,a,8,20,28);
}
void round2d(int32& a,int32& b,int32& c,int32& d)
{
a = gg(a,b,c,d,13,5,29);
d = gg(d,a,b,c,2,9,30);
c = gg(c,d,a,b,7,14,31);
b = gg(b,c,d,a,12,20,32);
}
void round3a(int32& a,int32& b,int32& c,int32& d)
{
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
/* [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]*/
a = hh(a,b,c,d,5,4,33);
d = hh(d,a,b,c,8,11,34);
c = hh(c,d,a,b,11,16,35);
b = hh(b,c,d,a,14,23,36);
}
void round3b(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,1,4,37);
d = hh(d,a,b,c,4,11,38);
c = hh(c,d,a,b,7,16,39);
b = hh(b,c,d,a,10,23,40);
}
void round3c(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,13,4,41);
d = hh(d,a,b,c,0,11,42);
c = hh(c,d,a,b,3,16,43);
b = hh(b,c,d,a,6,23,44);
}
void round3d(int32& a,int32& b,int32& c,int32& d)
{
a = hh(a,b,c,d,9,4,45);
d = hh(d,a,b,c,12,11,46);
c = hh(c,d,a,b,15,16,47);
b = hh(b,c,d,a,2,23,48);
}
void round4a(int32& a,int32& b,int32& c,int32& d)
{
}
void round4b(int32& a,int32& b,int32& c,int32& d)
{
}
void round4c(int32& a,int32& b,int32& c,int32& d)
{
}
void round4d(int32& a,int32& b,int32& c,int32& d)
{
}
void main()
{
int i,j;
int32 extmssg[16],aa,bb,cc,dd,a,b,c,d;
for(i=0;i<16;i++)
{
extmssg[i]=0;
}
extmssg[0] = 1;
extmssg[14] = md5length;
a = 0x01234567;
b = 0x89abcdef;
c = 0xfedcba98;
d = 0x76543210;
for(i=0;i<=((md5length/32)/16-2);i++) //-2 b/c of goofy extmssg idea
{
for(j=0;j<=15;j++)
{
workmssg[j] = read_program_eeprom((i*16)+j);
}
aa=a;
bb=b;
cc=c;
dd=d;
round1a(a,b,c,d);
round1b(a,b,c,d);
round1c(a,b,c,d);
// round1d(a,b,c,d);
// round2a(a,b,c,d);
// round2b(a,b,c,d);
// round2c(a,b,c,d);
// round2d(a,b,c,d);
// round3a(a,b,c,d);
// round3b(a,b,c,d);
// round3c(a,b,c,d);
// round3d(a,b,c,d);
// round4a(a,b,c,d);
// round4b(a,b,c,d);
// round4c(a,b,c,d);
// round4d(a,b,c,d);
a += aa;
b += bb;
c += cc;
d += dd;
}
//md5 done, result is DCBA
}
|
Last edited by treitmey on Thu Jul 21, 2005 7:49 am; edited 3 times in total |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Jul 20, 2005 3:53 pm |
|
|
Quote: |
I was trying to write an MD5 routine using the MD5 specification (rfc1321) and I ran out of ROM. Has anyone written a simpler version or done this another way?
|
MD5 mostly is running in 32 bit machines and it was conceived for that I guess.
Donīt know if somebody had ported to 8 bit. If you are out of ROM, I would get
the PCH and swap to 18F family without any change in the hardware.
Reading your code I guess that it is an important working project not just an evening hobby.
Best wishes,
Humberto
Regarding multiple posting
Could be possible to modify the handler in such a way that when the "button_click"
Submit is pressed once, it can disable itself to ovoid sucesive postings.? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|