variable changing by itself?

Ok, I can't look at this code any longer. I am trying to write my own sha256 algorithm. Why? I don't know, it seemed like a good idea, and how else am I suppose to get good at bitwise programming. :)
here is the problem. I was getting segmentation faults while creating the padding.
For those of you that are good at coding but have never done something like this, the padding is supposed to be a multiple of 512 bits. The input message (argv[1]) followed by a '1' bit and a series of '0' bits up to bit 448 or
( 512 * n ) + 448. followed by a 64 bit number, detailing the length of the message.
I have finally added a bunch of debug messages and discoverd the problem is whith the variable "msgsize_bit", however I have no idea why. It begins life as a relatively small number ( number of input characters * 8) and ends up being
friggin huge!!!. Why??? I'm tired of looking at this code and really could use some help. Here it is.... everything below the padding section is should be commented out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#define DEBUG 2
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
typedef unsigned int uint;
typedef unsigned long int uint32_t;
typedef unsigned long long int uint64_t;

union block
{
	char msg[];
	uint32_t word[];
};

int main(int argc, char* argv[])
    {
    if( !argv[1] )
    {
        cout <<"you did it wrong!\n ";
        return -1;
    }

    /************************************PADDING********************************/

    /* the number of bits in the message. placed convieniently in a 64bit type */
    const uint64_t msgsize_bit = strlen( argv[1] ) * 8;
    if(DEBUG > 0) cout << "Bitwise message size:\t" << msgsize_bit <<endl;
    /* quantum number of 512 blocks required */
    uint blocks = ceil( ((float)msgsize_bit + 1 + 64) / 512 );
    if(DEBUG > 0) cout << "No. of 512 bit blocks:\t" << blocks <<endl;
    /* The actual number of BYTES that the message will be padded to */
    uint padlength = (512 * blocks) / 8;
    if(DEBUG > 0) cout << "Overall padding length (bytes):\t" << padlength <<endl;
    /* this is a union so the message can later be accessed in chunks */
    block padding;
    if(DEBUG > 1) cout << "Initilizing padding block."<<endl;
    /* Creates a character array of padlength + 1, including the null bit */
    padding.msg[ padlength ];
    if(DEBUG > 1) cout << "Generating padding array."<<endl;
    /* insert the actual message in to the padding at position zero*/
    memcpy(&padding.msg[0] , argv[1] , strlen(argv[1]) );
    if(DEBUG > 1) cout << "Copying message to padding block."<<endl;
    /* Since the final padded length has to be a multiple of 512, we know */
    /* that the final digits are 64 bits and the message is a multiple of */
    /* 8 bits. the padding (1 and consecutive zeros) must be at least     */
    /* 8 bits. therefore the next few lines should be a safe assumption.  */
    padding.msg[ strlen( argv[1] ) ] = 0x80;
    if(DEBUG > 1) cout << "Generating padding start bit."<<endl;
    if(DEBUG > 1) cout << "Original message size (bits):" <<msgsize_bit<<endl;
    uint fillerbits = ((padlength * 8) - 64 - msgsize_bit);
    if(DEBUG > 1) cout << "Calculating required Filler padding bits, "<< fillerbits <<endl;
    uint nullbytes = (fillerbits / 8) - 1;
    if(DEBUG > 1) cout << "Calculating required NULL padding bytes, "<< nullbytes <<endl;
    int pos = 1;
    while( (pos-1) < nullbytes )
    {
	    padding.msg[ strlen( argv[1] ) + pos ] = 0x00;
	    if(DEBUG > 1) cout << "Added NULL bit at padding position ("<< strlen( argv[1] ) + pos<<"/"<< fillerbits <<")"<<endl;
	    pos++;
	}
    /* These next few lines append the last 64 bits of the padding with the */
    /* bit length of the message. Bitwise operation is necessary to ensure  */
    /* that the casted 64 bit integer actually consumes 64 bits             */
    //msgsize_bit = (msgsize_bit | 0x0000000000000000);
    memcpy(&padding.msg[ padlength - 8 ] , &msgsize_bit , 8 ); 
    cout <<padding.msg<<endl;
    /**********************************PARSING*******************************/

    /* According to FIPS180-4, SHA-256 the padded message (Mij) is to be    */
    /* is to be broken in to i 512 bit blocks and j 32-bit words            */
    /* i is cardinal, j is ordinal*/
    
    /*
    long *parsemsg_blocks[ blocks + 1 ][ 16 ];
    #define M(i,j) parsemsg_blocks[i+1][j]
    for(int x = 1; x >= blocks; x++)
    {
	    M(x,0) = &padding[0]
	     
	}
    cout << *M(1,0)<<endl;
    */
    
    
	return 0;
}
You need to fill in the array sizes
1
2
3
4
5
union block
{
	char msg[];
	uint32_t word[];
};
arrrrrggggg!!!!!
That makes sense I guess. Unfortunately that totally screws over what I am trying to do.
can anyone recommend a better way of doing this since I can't predict the size of the input in advance.
If you want a variable length buffer type, make a variable length buffer type. It can trivially implemented using std::vector<char>.
Topic archived. No new replies allowed.