Help! Program will not compile!

TI-82, TI-83 (plus, silver..), TI-84, TI-85 and TI-86
Post Reply
XTRMan1
New member
Posts: 7
Joined: Sun Oct 04, 2009 3:48 am

Help! Program will not compile!

Post by XTRMan1 »

I am receiving many errors when trying to compile the following code:
Error log: http://pastebin.org/84467

Code: Select all

#include <string.h>
#include "Crypto.h"

const uint32 sha256_k[] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};

struct SHA256_STATE {
    uint32 h[8];
};

void sha256_transform(struct SHA256_STATE* st, byte* buf) {
    uint32 w[64], s0, s1, t1, maj, ch, a = st->h[0], b = st->h[1], c = st->h[2], d = st->h[3], e = st->h[4], f = st->h[5], g = st->h[6], h = st->h[7];
    uint8 j;
    memcpy(w, buf, 64);
    for (j = 0; j < 16; j++) {
        w[j] = swap_endian_32(w[j]);
    }

    for (j = 16; j < 64; j++) {
        s0 = ROTR(w[j - 15], 7) ^ ROTR(w[j - 15], 18) ^ (w[j - 15] >> 3);
        s1 = ROTR(w[j - 2], 17) ^ ROTR(w[j - 2], 19) ^ (w[j - 2] >> 10);
        w[j] = w[j - 16] + s0 + w[j - 7] + s1;
    }

    for (j = 0; j < 64; j++) {
        s0 = ROTR(a, 2) ^ ROTR(a, 13) ^ ROTR(a, 22);
        s1 = ROTR(e, 6) ^ ROTR(e, 11) ^ ROTR(e, 25);
        maj = (a & b) ^ (a & c) ^ (b & c);
        ch = (e & f) ^ ((~e) & g);
        t1 = h + s1 + ch + sha256_k[j] + w[j];
        h = g;
        g = f;
        f = e;
        e = d + t1;
        d = c;
        c = b;
        b = a;
        a = t1 + s0 + maj;
    }

    st->h[0] += a;
    st->h[1] += b;
    st->h[2] += c;
    st->h[3] += d;
    st->h[4] += e;
    st->h[5] += f;
    st->h[6] += g;
    st->h[7] += h;
}

byte* SHA224(byte* msg, uint16 length, byte* ret) {
    byte buf[64];
    uint32 cCount = length * 8;
    uint8 i;
    struct SHA256_STATE st;
    st.h[0] = 0xc1059ed8;
    st.h[1] = 0x367cd507;
    st.h[2] = 0x3070dd17;
    st.h[3] = 0xf70e5939;
    st.h[4] = 0xffc00b31;
    st.h[5] = 0x68581511;
    st.h[6] = 0x64f98fa7;
    st.h[7] = 0xbefa4fa4;
    while (length > 0) {
        if (length >= 64) {
            sha256_transform(&st, msg);
            length -= 64;
            msg += 64;
        } else {
            memcpy(buf, msg, length);
            break;
        }
    }
    buf[length++] = (byte) 0x80;
    if (length > 56) {
        while (length < 64) {
            buf[length++] = (byte) 0;
        }
        sha256_transform(&st, buf);
        length = 0;
    }
    while (length < 56) {
        buf[length++] = (byte) 0;
    }
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = ((cCount >> 24) & 0xFF);
    buf[length++] = ((cCount >> 16) & 0xFF);
    buf[length++] = ((cCount >> 8) & 0xFF);
    buf[length++] = (cCount & 0xFF);
    sha256_transform(&st, buf);
    for (i = 0; i < 8; i++) {
        st.h[i] = swap_endian_32(st.h[i]);
    }
    memcpy(ret, st.h, 28);
    return ret;
}

byte* SHA256(byte* msg, uint16 length, byte* ret) {
    byte buf[64];
    uint32 cCount = length * 8;
    uint8 i;
    struct SHA256_STATE st;
    st.h[0] = 0x6a09e667;
    st.h[1] = 0xbb67ae85;
    st.h[2] = 0x3c6ef372;
    st.h[3] = 0xa54ff53a;
    st.h[4] = 0x510e527f;
    st.h[5] = 0x9b05688c;
    st.h[6] = 0x1f83d9ab;
    st.h[7] = 0x5be0cd19;
    while (length > 0) {
        if (length >= 64) {
            sha256_transform(&st, msg);
            length -= 64;
            msg += 64;
        } else {
            memcpy(buf, msg, length);
            break;
        }
    }
    buf[length++] = (byte) 0x80;
    if (length > 56) {
        while (length < 64) {
            buf[length++] = (byte) 0;
        }
        sha256_transform(&st, buf);
        length = 0;
    }
    while (length < 56) {
        buf[length++] = (byte) 0;
    }
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = ((cCount >> 24) & 0xFF);
    buf[length++] = ((cCount >> 16) & 0xFF);
    buf[length++] = ((cCount >> 8) & 0xFF);
    buf[length++] = (cCount & 0xFF);
    sha256_transform(&st, buf);
    for (i = 0; i < 8; i++) {
        st.h[i] = swap_endian_32(st.h[i]);
    }
    memcpy(ret, st.h, 32);
    return ret;
}
Last edited by XTRMan1 on Sun Jan 31, 2010 5:17 am, edited 1 time in total.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Defining the following:

Code: Select all

typedef unsigned long uint32;
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned int uint16;
Permits compilation, I've not access to Crypto.h - are they defined in there?
XTRMan1
New member
Posts: 7
Joined: Sun Oct 04, 2009 3:48 am

Post by XTRMan1 »

Those are defined in Crypto.h, but I still get the errors above when compiling with zcc +ti8x -c SHA256.c

Crypto.h:

Code: Select all

#ifndef _CRYPTO_H
#define _CRYPTO_H
#define ROTR(x,i) (((x) >> (i))| ((x) << ((sizeof(x) << 3) - (i))))
#define ROTL(x,i) (((x) << (i))| ((x) >> ((sizeof(x) << 3) - (i))))

typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long int uint32;

uint16 swap_endian_16(uint16);
uint32 swap_endian_32(uint32);
char* hex_string(byte* in, uint16 length, char* out);
byte* byte_array(char* in, uint16 length, byte* out);

byte* SHA1(byte* msg, uint16 length, byte* ret);
byte* SHA224(byte* msg, uint16 length, byte* ret);
byte* SHA256(byte* msg, uint16 length, byte* ret);

#define AES_PAD_NONE 0
#define AES_PAD_ZERO 1
#define AES_PAD_PKCS 2

#define AES_ERR_NONE 0
#define AES_ERR_KEYSIZE -1
#define AES_ERR_DATALENGTH -2
#define AES_ERR_PAD -3

typedef struct AES_CTX_T {
    byte RoundKey[240];
    byte state[16];
    byte Nr;
    uint8 padMode;
}AES_CTX;

int AES_INIT(AES_CTX* ctx, byte* key, uint8 keySize, uint8 pad);
void AES_ENCRYPT_BLOCK(AES_CTX* ctx, byte* data, byte* out);
void AES_DECRYPT_BLOCK(AES_CTX* ctx, byte* data, byte* out);
int AES_ENCRYPT(AES_CTX* ctx, byte* data, uint8 length, byte* out, uint8 *outLength);
int AES_DECRYPT(AES_CTX* ctx, byte* data, uint8 length, byte* out, uint8 *outLength);
void AES_DESTROY(AES_CTX* ctx);

#endif
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

XTRMan1 wrote:typedef unsigned long int uint32;
should be:

typedef unsigned long uint32;
XTRMan1
New member
Posts: 7
Joined: Sun Oct 04, 2009 3:48 am

Post by XTRMan1 »

Thanks. Changed but it still will not compile. It ouputs something about an invalid expression.
Error log:http://pastebin.org/84467
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I tried again this time with the crypto.h header and get the same result as you.

The problem is the compiler is not accepting "sizeof(w[j-1])" when w is declared as "uint32 w[64]". In fact any argument to sizeof involving an array indexing is rejected. I *think* this is legal C but I don't have a reference at hand to check and a quick google is not returning decisive or reliable answers.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

No comments :-) ?

It's definitely a bug in the compiler.

Here's some test code:

Code: Select all

int a[100];

main()
{
   sizeof(a);
   sizeof(a) / sizeof(a[0]);
}
The compiler will not accept "sizeof(a[0])". This not an uncommon idiom...
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

More an omission :)

I've committed some code for the case where the index is a constant. Doesn't help in the case in this thread of course.
XTRMan1
New member
Posts: 7
Joined: Sun Oct 04, 2009 3:48 am

Post by XTRMan1 »

Sorry computer was down for a while. Changing the sizeof(x) to 32 fixes the previous errors, but I am now getting some symbol undefined rules. By the way all of this code compiles using gcc.
Error log:http://pastebin.org/89266

Thanks
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

XTRMan1 wrote:Sorry computer was down for a while. Changing the sizeof(x) to 32 fixes the previous errors, but I am now getting some symbol undefined rules. By the way all of this code compiles using gcc.
Error log:http://pastebin.org/89266
sizeof(x) should be 4 as in 4 bytes. I made the same mistake initially until I looked at the produced code and found it shifting a 32 bit number by 240 bits :-D

Replacing the sizeof by 4 in the ROT macros solves the problem for me but I am stopping at the assembler output. Could you have forgotten to define the two swap_endian() functions?

Also the code generated contains tons of stack manipulations because a lot of variables are declared locally to functions (these are allocated on the stack and the z80 is not too good at stack addressing). You will get significan tspeed up and memory size reduction by using gloval vars as temp variables rather than local vars for your longs and long arrays. Of course doing this would mean the functions are no longer reentrant but that wouldn't matter unless you are trying to multitask :-)

Note to self, dom and stef: The quality of code generated would benefit greatly by having the compiler spot shifts of mutliples of 8 bits. A 32 bit number in dehl shifted right by 8 bits can be done with "ld l,h ; ld h,e ; ld e,d ; ld d,0" rather than a call to the bit shifter which would loop 8 times. Similarly I think we need to add special case multiplication and divides for 8,16,32 bit math. There are many places in the libraries where I'm multiplying by quanitites I know are 8 bit but I'm using the egneric 16-bit multiply.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

alvin wrote:Note to self, dom and stef: The quality of code generated would benefit greatly by having the compiler spot shifts of mutliples of 8 bits. A 32 bit number in dehl shifted right by 8 bits can be done with "ld l,h ; ld h,e ; ld e,d ; ld d,0" rather than a call to the bit shifter which would loop 8 times. Similarly I think we need to add special case multiplication and divides for 8,16,32 bit math. There are many places in the libraries where I'm multiplying by quanitites I know are 8 bit but I'm using the egneric 16-bit multiply.
8 bit shifts of 16 bit quantities are picked up by the optimiser and replaced with register operations, similarly multiplying a 16 bit int by a small constant is also speed optimised by addition as necessary.

I think the shift shortcuts could be pushed into the compiler rather than the optimiser though.
XTRMan1
New member
Posts: 7
Joined: Sun Oct 04, 2009 3:48 am

Post by XTRMan1 »

alvin wrote:

sizeof(x) should be 4 as in 4 bytes. I made the same mistake initially until I looked at the produced code and found it shifting a 32 bit number by 240 bits :-D
Yah, sorry I meant that I replaced (sizeof(x) << 3) with 32.
alvin wrote:

Replacing the sizeof by 4 in the ROT macros solves the problem for me but I am stopping at the assembler output. Could you have forgotten to define the two swap_endian() functions?
The swap_endian() functions are defined in a seperate file, but that shouldn't matter since I am only trying to compile to an object file and not link. Anyway this was the source of the errors. I declared both functions as extern (which I didn't have to when using gcc) and it now compiles.
alvin wrote:

Also the code generated contains tons of stack manipulations because a lot of variables are declared locally to functions (these are allocated on the stack and the z80 is not too good at stack addressing). You will get significan tspeed up and memory size reduction by using gloval vars as temp variables rather than local vars for your longs and long arrays. Of course doing this would mean the functions are no longer reentrant but that wouldn't matter unless you are trying to multitask :-)
Fixed, thanks. :)

Final Source:
Crypto.h:

Code: Select all

#ifndef _CRYPTO_H
#define _CRYPTO_H
#define ROTR(x,i) (((x) >> (i))| ((x) << (32 - (i))))
#define ROTL(x,i) (((x) << (i))| ((x) >> (32 - (i))))

typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;

extern uint16 swap_endian_16(uint16);
extern uint32 swap_endian_32(uint32);
char* hex_string(byte* in, uint16 length, char* out);
byte* byte_array(char* in, uint16 length, byte* out);

byte* SHA1(byte* msg, uint16 length, byte* ret);
byte* SHA224(byte* msg, uint16 length, byte* ret);
byte* SHA256(byte* msg, uint16 length, byte* ret);

#define AES_PAD_NONE 0
#define AES_PAD_ZERO 1
#define AES_PAD_PKCS 2

#define AES_ERR_NONE 0
#define AES_ERR_KEYSIZE -1
#define AES_ERR_DATALENGTH -2
#define AES_ERR_PAD -3

typedef struct AES_CTX_T {
    byte RoundKey[240];
    byte state[16];
    byte Nr;
    uint8 padMode;
}AES_CTX;

int AES_INIT(AES_CTX* ctx, byte* key, uint8 keySize, uint8 pad);
void AES_ENCRYPT_BLOCK(AES_CTX* ctx, byte* data, byte* out);
void AES_DECRYPT_BLOCK(AES_CTX* ctx, byte* data, byte* out);
int AES_ENCRYPT(AES_CTX* ctx, byte* data, uint8 length, byte* out, uint8 *outLength);
int AES_DECRYPT(AES_CTX* ctx, byte* data, uint8 length, byte* out, uint8 *outLength);
void AES_DESTROY(AES_CTX* ctx);

#endif
SHA256.c:

Code: Select all

#include <string.h>
#include "Crypto.h"

const uint32 sha256_k[] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};

byte buf[64];

struct SHA256_STATE {
    uint32 h[8];
}st;

void sha256_transform(struct SHA256_STATE* st, byte* buf) {
    uint32 w[64], s0, s1, t1, maj, ch, a = st->h[0], b = st->h[1], c = st->h[2], d = st->h[3], e = st->h[4], f = st->h[5], g = st->h[6], h = st->h[7];
    uint8 j;
    memcpy(w, buf, 64);
    for (j = 0; j < 16; j++) {
        w[j] = swap_endian_32(w[j]);
    }

    for (j = 16; j < 64; j++) {
        s0 = ROTR(w[j - 15], 7) ^ ROTR(w[j - 15], 18) ^ (w[j - 15] >> 3);
        s1 = ROTR(w[j - 2], 17) ^ ROTR(w[j - 2], 19) ^ (w[j - 2] >> 10);
        w[j] = w[j - 16] + s0 + w[j - 7] + s1;
    }

    for (j = 0; j < 64; j++) {
        s0 = ROTR(a, 2) ^ ROTR(a, 13) ^ ROTR(a, 22);
        s1 = ROTR(e, 6) ^ ROTR(e, 11) ^ ROTR(e, 25);
        maj = (a & b) ^ (a & c) ^ (b & c);
        ch = (e & f) ^ ((~e) & g);
        t1 = h + s1 + ch + sha256_k[j] + w[j];
        h = g;
        g = f;
        f = e;
        e = d + t1;
        d = c;
        c = b;
        b = a;
        a = t1 + s0 + maj;
    }

    st->h[0] += a;
    st->h[1] += b;
    st->h[2] += c;
    st->h[3] += d;
    st->h[4] += e;
    st->h[5] += f;
    st->h[6] += g;
    st->h[7] += h;
}

byte* SHA224(byte* msg, uint16 length, byte* ret) {
    uint32 cCount = length * 8;
    uint8 i;
    st.h[0] = 0xc1059ed8;
    st.h[1] = 0x367cd507;
    st.h[2] = 0x3070dd17;
    st.h[3] = 0xf70e5939;
    st.h[4] = 0xffc00b31;
    st.h[5] = 0x68581511;
    st.h[6] = 0x64f98fa7;
    st.h[7] = 0xbefa4fa4;
    while (length > 0) {
        if (length >= 64) {
            sha256_transform(&st, msg);
            length -= 64;
            msg += 64;
        } else {
            memcpy(buf, msg, length);
            break;
        }
    }
    buf[length++] = (byte) 0x80;
    if (length > 56) {
        while (length < 64) {
            buf[length++] = (byte) 0;
        }
        sha256_transform(&st, buf);
        length = 0;
    }
    while (length < 56) {
        buf[length++] = (byte) 0;
    }
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = ((cCount >> 24) & 0xFF);
    buf[length++] = ((cCount >> 16) & 0xFF);
    buf[length++] = ((cCount >> 8) & 0xFF);
    buf[length++] = (cCount & 0xFF);
    sha256_transform(&st, buf);
    for (i = 0; i < 8; i++) {
        st.h[i] = swap_endian_32(st.h[i]);
    }
    memset(buf, 0, 64);
    memcpy(ret, st.h, 28);
    return ret;
}

byte* SHA256(byte* msg, uint16 length, byte* ret) {
    uint32 cCount = length * 8;
    uint8 i;
    st.h[0] = 0x6a09e667;
    st.h[1] = 0xbb67ae85;
    st.h[2] = 0x3c6ef372;
    st.h[3] = 0xa54ff53a;
    st.h[4] = 0x510e527f;
    st.h[5] = 0x9b05688c;
    st.h[6] = 0x1f83d9ab;
    st.h[7] = 0x5be0cd19;
    while (length > 0) {
        if (length >= 64) {
            sha256_transform(&st, msg);
            length -= 64;
            msg += 64;
        } else {
            memcpy(buf, msg, length);
            break;
        }
    }
    buf[length++] = (byte) 0x80;
    if (length > 56) {
        while (length < 64) {
            buf[length++] = (byte) 0;
        }
        sha256_transform(&st, buf);
        length = 0;
    }
    while (length < 56) {
        buf[length++] = (byte) 0;
    }
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = 0;
    buf[length++] = ((cCount >> 24) & 0xFF);
    buf[length++] = ((cCount >> 16) & 0xFF);
    buf[length++] = ((cCount >> 8) & 0xFF);
    buf[length++] = (cCount & 0xFF);
    sha256_transform(&st, buf);
    for (i = 0; i < 8; i++) {
        st.h[i] = swap_endian_32(st.h[i]);
    }
    memset(buf, 0, 64);
    memcpy(ret, st.h, 32);
    return ret;
}
Post Reply