Thread: Help needed with compilation

  1. #1
    Registered User
    Join Date
    Aug 2016
    Posts
    1

    Help needed with compilation

    Edit: I've got it sorted. It was just a silly typo. BTW source code comes from: C or C++ code for validating Bitcoin addresses

    Hi

    I'm trying to compile a C program that verifies correctness of a bitcoin address
    Code:
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdlib.h>
    #include <openssl/sha.h>
    
    /* Based on libbase58, see https://github.com/luke-jr/libbase58 for reference.*/
    /* Returns the version of a valid Bitcoin address or a negative value if the  */
    /* address is invalid.                                                        */
    int validate_bitcoin_address(const char *address) {
        static const int8_t b58digits_map[] = {
            -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
            -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
            -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
            -1, 0, 1, 2, 3, 4, 5, 6,  7, 8,-1,-1,-1,-1,-1,-1,
            -1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
            22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
            -1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
            47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
        };
    
        unsigned char addrbin[25];
        size_t addrbinsz = sizeof(addrbin);
    
        void *bin = (void *) addrbin;
        size_t *binszp = &addrbinsz;
        const char *b58 = address;
        size_t b58sz = strlen(address);
    
        {
            const unsigned char *b58u = (void *) b58;
            unsigned char *binu = bin;
            uint32_t outi[(25 + 3) / 4];
            size_t outisz=(25 + 3) / 4;
            uint64_t t;
            uint32_t c;
            size_t i, j;
            uint8_t bytesleft = 25 % 4;
            uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
            unsigned zerocount = 0;
    
            if (!b58sz) b58sz = strlen(b58);
            memset(outi, 0, sizeof(outi));
    
            /* Leading zeros, just count */
            for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount;
            for ( ; i < b58sz; ++i) {
                if (b58u[i] & 0x80) return -1; /* High-bit set on invalid digit */
                if (b58digits_map[b58u[i]] == -1) return -2; /* Invalid base58 digit */
                
                c = (unsigned)b58digits_map[b58u[i]];
                for (j = outisz; j--; ) {
                    t = ((uint64_t)outi[j]) * 58 + c;
                    c = (t & 0x3f00000000) >> 32;
                    outi[j] = t & 0xffffffff;
                }
    
                if (c) return -3; /* Output number too big (carry to the next int32) */
                if (outi[0] & zeromask) return -4; /* Output number too big (last int32 filled too far) */
            }
    
            j = 0;
            switch (bytesleft) {
                case 3: *(binu++) = (outi[0] &   0xff0000) >> 16;
                case 2: *(binu++) = (outi[0] &     0xff00) >>  8;
                case 1: *(binu++) = (outi[0] &       0xff);  ++j;
                default: break;
            }
    
            for (; j < outisz; ++j) {
                *(binu++) = (outi[j] >> 0x18) & 0xff;
                *(binu++) = (outi[j] >> 0x10) & 0xff;
                *(binu++) = (outi[j] >>    8) & 0xff;
                *(binu++) = (outi[j] >>    0) & 0xff;
            }
    
            binu = bin; /* Count canonical base58 byte count */
            for (i = 0; i < 25; ++i) {
                if (binu[i]) break;
                --*binszp;
            }
            *binszp += zerocount;
        }
    
        if (addrbinsz != 25) return -5;
        if (addrbin[0] != 0 && addrbin[0] != 5) return -6;
    
        {
            unsigned char d1[SHA256_DIGEST_LENGTH], d2[SHA256_DIGEST_LENGTH];
            SHA256(SHA256(addrbin, 21, d1), SHA256_DIGEST_LENGTH, d2);
            if (memcmp(addrbin + 21, d2, 4)) return -7;
        }
    
        return addrbin[0];
    }
    
    int main( int argc, char * argv [] ) {
        int i;
    
        for (i = 1; i < argc; ++i ) {
            bool valid = (validate_bitcoin_address(argv[i]) >= 0);
            printf( "%s is %s\n", argv[i], valid ? "VALID." : "INVALID!");
        }
    
        return 0;
    }
    What I get is this:
    Code:
    $ gcc -Wall veradd.c -o verify
    /tmp/ccxAKGEq.o: In function `validate_bitcoin_address':
    veradd.c:(.text+0x378): undefined reference to `SHA256'
    veradd.c:(.text+0x392): undefined reference to `SHA256'
    collect2: error: ld returned 1 exit status
    or alternatively:
    Code:
    $ gcc -Wall veradd.c -o verify -lcrypto
    compiles no bother but when I want to run this it looks like it doesn't start.
    I had a look at GitHub - luke-jr/libbase58: C library for Bitcoin's base58 encoding where the source code is derived from and it said something about initialising a SHA256 but alas being complete noob I couldn't figure out how to make it work.
    My settings:
    Code:
    $ uname -r; openssl version;gcc --version
    4.4.16-1-lts
    OpenSSL 1.0.2h  3 May 2016
    gcc (GCC) 6.1.1 20160802
    Last edited by PepaPig; 08-10-2016 at 10:08 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why JIT compilation and not full compilation?
    By C_ntua in forum General Discussions
    Replies: 8
    Last Post: 01-10-2013, 02:33 AM
  2. c compilation
    By herWter in forum C Programming
    Replies: 6
    Last Post: 07-28-2008, 01:51 PM
  3. Pro*C Compilation.
    By asif_oracle in forum C Programming
    Replies: 4
    Last Post: 04-01-2008, 09:41 AM
  4. PC RAM in Compilation
    By SlyMaelstrom in forum Tech Board
    Replies: 5
    Last Post: 05-21-2006, 06:03 AM
  5. Explanation of a Compilation Error Needed
    By Zildjian in forum C Programming
    Replies: 2
    Last Post: 10-23-2003, 02:04 AM

Tags for this Thread