CBByteArray * CBVersionChecksumBytesGetString(CBVersionChecksumBytes * self) {
    if (self->cachedString) {
        // Return cached string
        CBRetainObject(self->cachedString);
        return self->cachedString;
    } else {
        // Make string
        CBByteArrayReverseBytes(CBGetByteArray(self)); // Make this into little-endian
        CBBigInt bytes;
        CBBigIntAlloc(&bytes, CBGetByteArray(self)->length);
        bytes.length = CBGetByteArray(self)->length;
        memcpy(bytes.data, CBByteArrayGetData(CBGetByteArray(self)), bytes.length);
        char * string = CBEncodeBase58(&bytes);
        if (NOT string)
            return NULL;
        CBByteArray * str = CBNewByteArrayFromString(string, true, CBGetByteArray(self)->logError);
        if (NOT str) {
            free(string);
            return NULL;
        }
        CBByteArrayReverseBytes(CBGetByteArray(self)); // Now the string is got, back to big-endian.
        if (self->cacheString) {
            self->cachedString = str;
            CBRetainObject(str); // Retain for this object.
        }
        return str; // No additional retain. Retained from constructor.
    }
}
static void
send_version() 
{
    CBByteArray *ip = CBNewByteArrayWithDataCopy((uint8_t [16]){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 127, 0, 0, 1}, 16);
    CBByteArray *ua = CBNewByteArrayFromString("cmsc417versiona", '\00');
    CBNetworkAddress * sourceAddr = CBNewNetworkAddress(0, ip, 0, CB_SERVICE_FULL_BLOCKS, false);
    int32_t vers = 70001;
    int nonce = rand();
    CBVersion * version = CBNewVersion(vers, CB_SERVICE_FULL_BLOCKS, time(NULL), &peer->base, sourceAddr, nonce, ua, 0);
    CBMessage *message = CBGetMessage(version);
    char header[24];
    memcpy(header + CB_MESSAGE_HEADER_TYPE, "version\0\0\0\0\0", 12);

    /* Compute length, serialized, and checksum */
    uint32_t len = CBVersionCalculateLength(version);
    message->bytes = CBNewByteArrayOfSize(len);
    len = CBVersionSerialise(version, false);
    if (message->bytes) {
        // Make checksum
        uint8_t hash[32];
        uint8_t hash2[32];
        CBSha256(CBByteArrayGetData(message->bytes), message->bytes->length, hash);
        CBSha256(hash, 32, hash2);
        message->checksum[0] = hash2[0];
        message->checksum[1] = hash2[1];
        message->checksum[2] = hash2[2];
        message->checksum[3] = hash2[3];
    }
    CBInt32ToArray(header, CB_MESSAGE_HEADER_NETWORK_ID, NETMAGIC);
    CBInt32ToArray(header, CB_MESSAGE_HEADER_LENGTH, message->bytes->length);
    // Checksum
    memcpy(header + CB_MESSAGE_HEADER_CHECKSUM, message->checksum, 4);

    // Send the header
    send(sd, header, 24, 0);
    
    // Send the message
    printf("message len: %d\n", message->bytes->length);
    printf("checksum: %x\n", *((uint32_t *) message->checksum));
    send(sd, message->bytes->sharedData->data+message->bytes->offset, message->bytes->length, 0);
    print_hex(message->bytes);
}
Example #3
0
void BRSendVersion(BRConnection *c) {
    /* current version number according to http://bitcoin.stackexchange.com/questions/13537/how-do-i-find-out-what-the-latest-protocol-version-is */
    CBVersionServices services = CB_SERVICE_FULL_BLOCKS;
    int64_t t = time(NULL);
    CBNetworkAddress *r_addr = c->address;
    CBNetworkAddress *s_addr = c->my_address;
    uint64_t nonce = rand();
    CBByteArray *ua = CBNewByteArrayFromString("br_cmsc417_v0.1", false);
    int32_t block_height = 0; /* TODO get real number */

    CBVersion *v = CBNewVersion(VERSION_NUM, services, t, r_addr, s_addr,
            nonce, ua, block_height);
    uint32_t length = CBVersionCalculateLength(v);
    v->base.bytes = CBNewByteArrayOfSize(length);
    CBVersionSerialise(v, false);

    BRSendMessage(c, &v->base, "version");

    /* don't release remote and local addresses just yet.
     * need them for other messages */
    CBReleaseObject(ua);
    CBFreeVersion(v);
}
Example #4
0
int main(){
	CBByteArray * walletKeyString = CBNewByteArrayFromString("xpub6DRhpXssnj7X6CwJgseK9oyFxSC8jk6nJz2SWkf5pjsQs12xv89Dfr627TtaZKkFbG6Aq23fmaNaf5KRo9iGfEXTTXvtd6gsXJTB8Sdah3B", false);
    CBChecksumBytes * walletKeyData = CBNewChecksumBytesFromString(walletKeyString, false);
    CBHDKey * cbkey = CBNewHDKeyFromData(CBByteArrayGetData(CBGetByteArray(walletKeyData)));
	CBAddress * address = CBNewAddressFromRIPEMD160Hash(CBHDKeyGetHash(cbkey), CB_NETWORK_PRODUCTION, false);
	CBByteArray * str = CBChecksumBytesGetString(CBGetChecksumBytes(address));
	printf("%s\n", CBByteArrayGetData(str));
	CBReleaseObject(address);
	// Test type
	if (CBHDKeyGetType(CB_HD_KEY_VERSION_PROD_PRIVATE) != CB_HD_KEY_TYPE_PRIVATE) {
		printf("CB_HD_KEY_VERSION_PROD_PRIVATE TYPE FAIL\n");
		return EXIT_FAILURE;
	}
	if (CBHDKeyGetType(CB_HD_KEY_VERSION_PROD_PUBLIC) != CB_HD_KEY_TYPE_PUBLIC) {
		printf("CB_HD_KEY_VERSION_PROD_PUBLIC TYPE FAIL\n");
		return EXIT_FAILURE;
	}
	if (CBHDKeyGetType(CB_HD_KEY_VERSION_TEST_PRIVATE) != CB_HD_KEY_TYPE_PRIVATE) {
		printf("CB_HD_KEY_VERSION_TEST_PRIVATE TYPE FAIL\n");
		return EXIT_FAILURE;
	}
	if (CBHDKeyGetType(CB_HD_KEY_VERSION_TEST_PUBLIC) != CB_HD_KEY_TYPE_PUBLIC) {
		printf("CB_HD_KEY_VERSION_TEST_PUBLIC TYPE FAIL\n");
		return EXIT_FAILURE;
	}
	// Test HMAC-SHA512
	uint8_t hash[64];
	CBHDKeyHmacSha512((uint8_t [37]){0x2f, 0xf7, 0xd6, 0x9f, 0x7a, 0x59, 0x0b, 0xb0, 0x5e, 0x68, 0xd1, 0xdc, 0x0f, 0xcf, 0x8d, 0xc2, 0x17, 0x59, 0xc9, 0x39, 0xbb, 0x6b, 0x9b, 0x02, 0x0f, 0x65, 0x5d, 0x53, 0x85, 0x3c, 0xb5, 0xc2, 0x14, 0x61, 0x4b, 0x24, 0x42}, (uint8_t [32]){0xa2, 0x55, 0x21, 0xe3, 0xc5, 0x5b, 0x65, 0xd1, 0xcf, 0x25, 0x4b, 0x6c, 0x85, 0x23, 0xdc, 0xbf, 0x89, 0x46, 0x8d, 0x1f, 0x09, 0x1f, 0x15, 0x87, 0x6b, 0xbb, 0xc7, 0xfd, 0xd5, 0x44, 0x28, 0x43}, hash);
	if (memcmp(hash, (uint8_t [64]){0xfa, 0xa7, 0x9d, 0x85, 0xe0, 0xe4, 0x3d, 0xae, 0x8c, 0x3f, 0x99, 0xf0, 0x70, 0xdf, 0x97, 0x56, 0x2b, 0x3f, 0xbb, 0x17, 0x35, 0x20, 0xe0, 0x87, 0x32, 0xa6, 0x64, 0xca, 0xd4, 0x55, 0x0b, 0xbe, 0xc1, 0x11, 0xe5, 0xf8, 0x80, 0xdb, 0xb7, 0x3d, 0x67, 0x74, 0xbb, 0xc2, 0x9f, 0x67, 0xd9, 0x67, 0xaa, 0x10, 0xac, 0x60, 0x18, 0x90, 0x7f, 0x35, 0x53, 0xe3, 0x21, 0x38, 0xf6, 0x5b, 0xbe, 0x69}, 64) != 0) {
		printf("HMAC FAIL\n");
		return EXIT_FAILURE;
	}
	for (uint8_t x = 0; x < NUM_TEST_VECTORS; x++) {
		// Deserialise private key
		CBByteArray * masterString = CBNewByteArrayFromString(testVectors[x][0].privString, true);
		CBChecksumBytes * masterData = CBNewChecksumBytesFromString(masterString, false);
		CBReleaseObject(masterString);
		CBHDKey * key = CBNewHDKeyFromData(CBByteArrayGetData(CBGetByteArray(masterData)));
		CBReleaseObject(masterData);
		checkKey(key, x, 0);
		for (uint8_t y = 0; y < NUM_CHILDREN; y++) {
			if (testVectors[x][y+1].childID.priv == false) {
				// Derive public child and check public key is correct by address
				CBHDKey * newKey = CBNewHDKey(false);
				key->versionBytes = CB_HD_KEY_VERSION_PROD_PUBLIC;
				CBHDKeyDeriveChild(key, testVectors[x][y+1].childID, newKey);
				key->versionBytes = CB_HD_KEY_VERSION_PROD_PRIVATE;
				CBAddress * address = CBNewAddressFromRIPEMD160Hash(CBHDKeyGetHash(newKey), CB_NETWORK_PRODUCTION, false);
				CBByteArray * str = CBChecksumBytesGetString(CBGetChecksumBytes(address));
				CBReleaseObject(address);
				if (memcmp(CBByteArrayGetData(str), testVectors[x][y + 1].addr, 34) != 0) {
					printf("ADDR FROM PUB FAIL AT %u - %u\n", x, y + 1);
					exit(EXIT_FAILURE);
				}
				CBReleaseObject(str);
				// Check serialisation of public key
				uint8_t * keyData = malloc(82);
				CBHDKeySerialise(newKey, keyData);
				CBChecksumBytes * checksumBytes = CBNewChecksumBytesFromBytes(keyData, 82, false);
				str = CBChecksumBytesGetString(checksumBytes);
				CBReleaseObject(checksumBytes);
				if (memcmp(CBByteArrayGetData(str), testVectors[x][y+1].pubString, 111) != 0) {
					printf("PUBLIC KEY STRING FROM PUB FAIL AT %u - %u\n", x, y);
					exit(EXIT_FAILURE);
				}
				CBReleaseObject(str);
				free(newKey);
			}
			// Derive private child
			CBHDKey * newKey = CBNewHDKey(true);
			CBHDKeyDeriveChild(key, testVectors[x][y+1].childID, newKey);
			free(key);
			key = newKey;
			checkKey(key, x, y+1);
		}
		free(key);
	}
	return EXIT_SUCCESS;
}