Exemplo n.º 1
0
bool CBInitNetworkAddress(CBNetworkAddress * self, uint64_t lastSeen, CBByteArray * ip, uint16_t port, CBVersionServices services, bool isPublic){
	self->lastSeen = lastSeen;
	self->penalty = 0;
	self->ip = ip;
	self->isPublic = isPublic;
	if (NOT ip) {
		ip = CBNewByteArrayOfSize(16);
		if (NOT ip)
			return false;
		memset(CBByteArrayGetData(ip), 0, 16);
		self->type = CB_IP_INVALID;
	}else{
		// Determine IP type
		self->type = CBGetIPType(CBByteArrayGetData(ip));
		CBRetainObject(ip);
	}
	self->port = port;
	self->services = services;
	self->bucketSet = false;
	if (NOT CBInitMessageByObject(CBGetMessage(self))){
		CBReleaseObject(ip);
		return false;
	}
	return true;
}
Exemplo n.º 2
0
CBCompare CBByteArrayCompare(CBByteArray * self,CBByteArray * second){
	if (self->length > second->length)
		return CB_COMPARE_MORE_THAN;
	else if (self->length < second->length)
		return CB_COMPARE_LESS_THAN;
	return memcmp(CBByteArrayGetData(self), CBByteArrayGetData(second), self->length);
}
Exemplo n.º 3
0
bool CBAddressStorageSaveAddress(uint64_t iself, void * address){
	CBAddressStore * self = (CBAddressStore *)iself;
	CBNetworkAddress * addrObj = address;
	// Create key
	memcpy(CB_ADDRESS_KEY + 1, CBByteArrayGetData(addrObj->ip), 16);
	CBInt16ToArray(CB_ADDRESS_KEY, 17, addrObj->port);
	// Create data
	CBInt64ToArray(CB_DATA_ARRAY, 0, addrObj->lastSeen);
	CBInt64ToArray(CB_DATA_ARRAY, 8, (uint64_t) addrObj->services);
	CBInt32ToArray(CB_DATA_ARRAY, 16, addrObj->penalty);
	// Write data
	if (NOT CBDatabaseWriteValue(CBGetDatabase(self), CB_ADDRESS_KEY, CB_DATA_ARRAY, 20)) {
		CBLogError("Could not write an address to storage.");
		return false;
	}
	// Increase the number of addresses
	CBInt32ToArray(CB_DATA_ARRAY, 0, --self->numAddresses);
	if (NOT CBDatabaseWriteValue(CBGetDatabase(self), CB_ADDR_NUM_KEY, CB_DATA_ARRAY, 4)) {
		CBLogError("Could not write the new number of addresses to storage.");
		return false;
	}
	// Commit changes
	if (NOT CBDatabaseCommit(CBGetDatabase(self))) {
		CBLogError("Could not commit adding a new network address to storage.");
		return false;
	}
	return true;
}
Exemplo n.º 4
0
void BRHandleAddr(BRConnection *c, CBByteArray *message) {
    CBAddressBroadcast *b = CBNewAddressBroadcastFromData(message, true);
    CBAddressBroadcastDeserialise(b);

    int i;
    for (i = 0; i < b->addrNum; ++i) {
        CBByteArray *ba = b->addresses[i]->ip;
        uint8_t *addr = CBByteArrayGetData(ba);

        if (addr[10] == 0xFF && addr[11] == 0xFF) {
            /* octets:      255   .  255  .  255  .  255  \0 */
            char *ip = malloc(3 + 1 + 3 + 1 + 3 + 1 + 3 + 1);
            if (ip == NULL) {
                perror("malloc failed");
                exit(1);
            }
            sprintf(ip, "%d.%d.%d.%d", addr[12], addr[13], addr[14], addr[15]);
            printf("Found address %s on port %hu\n", ip, b->addresses[i]->port);

            BRConnector *connector = (BRConnector *) c->connector;
            BROpenConnection(connector, ip, b->addresses[i]->port);

            free(ip);
        } else {
            fprintf(stderr, "Real IPv6 addresses not supported\n");
            exit(1);
        }
    }

    CBFreeAddressBroadcast(b);
}
Exemplo n.º 5
0
uint8_t CBNetworkAddressDeserialise(CBNetworkAddress * self, bool timestamp){
	CBByteArray * bytes = CBGetMessage(self)->bytes;
	if (! bytes) {
		CBLogError("Attempting to deserialise a CBNetworkAddress with no bytes.");
		return 0;
	}
	if (bytes->length < 26 + timestamp * 4) {
		CBLogError("Attempting to deserialise a CBNetworkAddress with less bytes than required.");
		return 0;
	}
	uint8_t start;
	uint64_t twoHoursAgo = time(NULL) - 3600;
	if (timestamp) {
		// Make sure we do not set self->lastSeen later than one hour ago.
		self->lastSeen = CBByteArrayReadInt32(bytes, 0);
		if (self->lastSeen > twoHoursAgo)
			self->lastSeen = twoHoursAgo;
		start = 4;
	}else{
		self->lastSeen = twoHoursAgo;
		start = 0;
	}
	self->services = (CBVersionServices) CBByteArrayReadInt64(bytes, start);
	self->ip = CBNewByteArraySubReference(bytes, start + 8, 16);
	// Determine IP type
	self->type = CBGetIPType(CBByteArrayGetData(self->ip));
	self->port = CBByteArrayReadPort(bytes, start + 24);
	return start + 26;
}
Exemplo n.º 6
0
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.
    }
}
bool CBBlockChainStorageLoadOrphan(void * validator, uint8_t orphanNum){
	CBFullValidator * validatorObj = validator;
	CBDatabase * database = (CBDatabase *)validatorObj->storage;
	CB_ORPHAN_KEY[2] = orphanNum;
	uint32_t len = CBDatabaseGetLength(database, CB_ORPHAN_KEY);
	CBByteArray * orphanData = CBNewByteArrayOfSize(len);
	if (NOT orphanData) {
		CBLogError("There was an error when initialising a byte array for an orphan.");
		return false;
	}
	if (NOT CBDatabaseReadValue(database, CB_ORPHAN_KEY, CBByteArrayGetData(orphanData), len, 0)) {
		CBLogError("There was an error when reading the data for an orphan.");
		CBReleaseObject(orphanData);
		return false;
	}
	validatorObj->orphans[orphanNum] = CBNewBlockFromData(orphanData);
        CBBlockDeserialise(validatorObj->orphans[orphanNum], true);
	if (NOT validatorObj->orphans[orphanNum]) {
		CBLogError("There was an error when creating a block object for an orphan.");
		CBReleaseObject(orphanData);
		return false;
	}
	CBReleaseObject(orphanData);
	return true;
}
void * CBBlockChainStorageLoadBlock(void * validator, uint32_t blockID, uint32_t branch){
	CBFullValidator * validatorObj = validator;
	CBDatabase * database = (CBDatabase *)validatorObj->storage;
	CB_BLOCK_KEY[2] = branch;
	CBInt32ToArray(CB_BLOCK_KEY, 3, blockID);
	uint32_t blockDataLen = CBDatabaseGetLength(database, CB_BLOCK_KEY);
	if (NOT blockDataLen)
		return NULL;
	blockDataLen -= CB_BLOCK_START;
	// Get block data
	CBByteArray * data = CBNewByteArrayOfSize(blockDataLen);
	if (NOT data) {
		CBLogError("Could not initialise a byte array for loading a block.");
		return NULL;
	}
	if (NOT CBDatabaseReadValue(database, CB_BLOCK_KEY, CBByteArrayGetData(data), blockDataLen, CB_BLOCK_START)){
		CBLogError("Could not read a block from the database.");
		CBReleaseObject(data);
		return NULL;
	}
	// Make and return the block
	CBBlock * block = CBNewBlockFromData(data);
	CBReleaseObject(data);
	if (NOT block) {
		CBLogError("Could not create a block object when loading a block.");
		return NULL;
	}
	return block;
}
Exemplo n.º 9
0
void BRSendMessage(BRConnection *c, CBMessage *message, char *command) {
    /* partially adapted from examples/pingpong.c */
    char header[24] = {0}; /* zeros help us out places */
    
    memcpy(header + CB_MESSAGE_HEADER_TYPE, command, strlen(command));
    
    uint8_t hash[32];
    uint8_t hash2[32];
    if (message->bytes)
        CBSha256(CBByteArrayGetData(message->bytes), message->bytes->length, hash);
    else {
        /* Get the checksum right -- handles problem where checksum not calculated
         * for messages with no payload */
        CBSha256(NULL, 0, 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);
    if (message->bytes) {
        CBInt32ToArray(header, CB_MESSAGE_HEADER_LENGTH, message->bytes->length);
    }
    memcpy(header + CB_MESSAGE_HEADER_CHECKSUM, message->checksum, 4);

    int sent = send(c->sock, header, 24, 0);
    if (sent < 0) {
        perror("send failed");
        exit(1);
    }
    if (sent != 24) {
        fprintf(stderr, "send sent %d, not 24 bytes\n", sent);
        exit(1);
    }
    if (message->bytes) {
        sent = send(c->sock, message->bytes->sharedData->data + message->bytes->offset,
                    message->bytes->length, 0);
        if (sent < 0) {
            perror("send failed");
            exit(1);
        }
        if (sent != message->bytes->length) {
            fprintf(stderr, "send sent %d, not %d bytes\n", sent, message->bytes->length);
            exit(1);
        }
    }

#ifdef BRDEBUG
    print_header(header);
    printf("message len: %d\n", message->bytes ? message->bytes->length : 0);
    printf("checksum: %x\n", *((uint32_t *) message->checksum));
    print_hex(message->bytes);
    printf("\n");
#endif
}
bool CBBlockChainStorageSaveOrphan(void * validator, void * block, uint8_t orphanNum){
	CBFullValidator * validatorObj = validator;
	CBDatabase * database = (CBDatabase *)validatorObj->storage;
	CBBlock * blockObj = block;
	CB_ORPHAN_KEY[2] = orphanNum;
	if (NOT CBDatabaseWriteValue(database, CB_ORPHAN_KEY, CBByteArrayGetData(CBGetMessage(blockObj)->bytes), CBGetMessage(blockObj)->bytes->length)) {
		CBLogError("Could not write an orphan.");
		return false;
	}
	return true;
}
Exemplo n.º 11
0
int main(){
	unsigned int s = (unsigned int)time(NULL);
	printf("Session = %ui\n", s);
	srand(s);
	// Test string
	char * string = "Hello World!";
	CBByteArray * ba = CBNewByteArrayWithDataCopy((uint8_t *)string, (uint32_t)strlen(string) + 1);
	if (strcmp(string, (char *)CBByteArrayGetData(ba))) {
		printf("STRING COPY FAIL\n");
		return 1;
	}
	return 0;
}
void * CBBlockChainStorageLoadUnspentOutput(void * validator, uint8_t * txHash, uint32_t outputIndex, bool * coinbase, uint32_t * outputHeight){
	CBFullValidator * validatorObj = validator;
	CBDatabase * database = (CBDatabase *)validatorObj->storage;
	// First read data for the unspent output key.
	memcpy(CB_UNSPENT_OUTPUT_KEY + 2, txHash, 32);
	CBInt32ToArray(CB_UNSPENT_OUTPUT_KEY, 34, outputIndex);
	if (NOT CBDatabaseReadValue(database, CB_UNSPENT_OUTPUT_KEY, CB_DATA_ARRAY, 8, 0)) {
		CBLogError("Cannot read unspent output information from the block chain database");
		return NULL;
	}
	uint32_t outputPosition = CBArrayToInt32(CB_DATA_ARRAY, CB_UNSPENT_OUTPUT_REF_POSITION);
	uint32_t outputLength = CBArrayToInt32(CB_DATA_ARRAY, CB_UNSPENT_OUTPUT_REF_LENGTH);
	// Now read data for the transaction
	memcpy(CB_TRANSACTION_INDEX_KEY + 2, txHash, 32);
	if (NOT CBDatabaseReadValue(database, CB_TRANSACTION_INDEX_KEY, CB_DATA_ARRAY, 14, 0)) {
		CBLogError("Cannot read a transaction reference from the transaction index.");
		return NULL;
	}
	uint8_t outputBranch = CB_DATA_ARRAY[CB_TRANSACTION_REF_BRANCH];
	uint32_t outputBlockIndex = CBArrayToInt32(CB_DATA_ARRAY, CB_TRANSACTION_REF_BLOCK_INDEX);
	// Set coinbase
	*coinbase = CB_DATA_ARRAY[CB_TRANSACTION_REF_IS_COINBASE];
	// Set output height
	*outputHeight = validatorObj->branches[outputBranch].startHeight + outputBlockIndex;
	// Get the output from storage
	CB_BLOCK_KEY[2] = outputBranch;
	CBInt32ToArray(CB_BLOCK_KEY, 3, outputBlockIndex);
	// Get output data
	CBByteArray * outputBytes = CBNewByteArrayOfSize(outputLength);
	if (NOT outputBytes) {
		CBLogError("Could not create  CBByteArray for an unspent output.");
		return NULL;
	}
	if (NOT CBDatabaseReadValue(database, CB_BLOCK_KEY, CBByteArrayGetData(outputBytes), outputLength, CB_BLOCK_START + outputPosition)) {
		CBLogError("Could not read an unspent output");
		CBReleaseObject(outputBytes);
		return NULL;
	}
	// Create output object
	CBTransactionOutput * output = CBNewTransactionOutputFromData(outputBytes);
	CBReleaseObject(outputBytes);
	if (NOT output) {
		CBLogError("Could not create an object for an unspent output");
		return NULL;
	}
	if (NOT CBTransactionOutputDeserialise(output)) {
		CBLogError("Could not deserialise an unspent output");
		return NULL;
	}
	return output;
}
Exemplo n.º 13
0
void CBRPCServerAcceptConnection(void * vself, CBDepObject socket){
	CBRPCServer * self = vself;
	CBSocketAddress sockAddr;
	if (! CBSocketAccept(socket, &self->connSocket, &sockAddr)){
		CBLogError("Could not accept RPC connection.");
		return;
	}
	// We want local connections.
	if (!(CBGetIPType(CBByteArrayGetData(sockAddr.ip)) & CB_IP_LOCAL)
		|| !CBRPCServerRespond(self, NULL, CB_HTTP_FORBIDDEN, false, CBRPCServerDisconnect)){
		CBRPCServerDisconnect(self);
		return;
	}
	
}
Exemplo n.º 14
0
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
		char * string = CBEncodeBase58(CBByteArrayGetData(CBGetByteArray(self)),CBGetByteArray(self)->length);
		CBByteArray * str = CBNewByteArrayWithData((uint8_t *)string, strlen(string), CBGetByteArray(self)->events);
		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.
	}
}
Exemplo n.º 15
0
int main(int argc, char * argv[]){

	bool encode = strcmp(argv[1],"-d");

	// Read comma sperated inputs from the second argument
	char * inputs[100], * comma;
	inputs[0] = argv[2];

	int num = 1;
	for (; (comma = strchr(argv[2], ',')); num++) {
		inputs[num] = comma + 1;
		*comma = '\0';
		argv[2] = comma + 1;
	}

	for (int x = 0; x < num; x++) {
		if (encode) {

			// Convert hex string into bytes and then encode base58 string
			CBByteArray * bytes = CBNewByteArrayFromHex(inputs[x]);
			CBByteArrayReverseBytes(bytes);
			CBBigInt bi = {CBByteArrayGetData(bytes), bytes->length, bytes->length};
			char * output = CBEncodeBase58(&bi);
			puts(output);
			free(output);
			CBReleaseObject(bytes);

		}else{

			// Decode base58 string and then produce data as a hex string.
			CBBigInt bi;
			CBBigIntAlloc(&bi, strlen(inputs[x]) * 100 / 136);
			CBDecodeBase58(&bi, inputs[x]);
			printf("0x");
			for (uint8_t x = bi.length; x--;)
				printf("%02x", bi.data[x]);
			puts("");
			free(bi.data);

		}
	}

}
Exemplo n.º 16
0
bool CBInitVersionChecksumBytesFromString(CBVersionChecksumBytes * self,CBByteArray * string,bool cacheString,CBEvents * events){
	// Cache string if needed
	if (cacheString) {
		self->cachedString = string;
		CBRetainObject(string);
	}else
		self->cachedString = NULL;
	self->cacheString = cacheString;
	// Get bytes from string conversion
	CBBigInt bytes = CBDecodeBase58Checked((char *)CBByteArrayGetData(string), events);
	if (bytes.length == 1) {
		return false;
	}
	// Take over the bytes with the CBByteArray
	if (NOT CBInitByteArrayWithData(CBGetByteArray(self), bytes.data, bytes.length, events))
		return false;
	CBByteArrayReverseBytes(CBGetByteArray(self)); // CBBigInt is in little-endian. Conversion needed to make bitcoin address the right way.
	return true;
}
Exemplo n.º 17
0
bool CBInitVersionChecksumBytesFromString(CBVersionChecksumBytes * self,CBByteArray * string,bool cacheString,void (*logError)(char *,...)) {
    // Cache string if needed
    if (cacheString) {
        self->cachedString = string;
        CBRetainObject(string);
    } else
        self->cachedString = NULL;
    self->cacheString = cacheString;
    // Get bytes from string conversion
    CBBigInt bytes;
    CBBigIntAlloc(&bytes, 25); // 25 is the number of bytes for bitcoin addresses.
    if (NOT CBDecodeBase58Checked(&bytes, (char *)CBByteArrayGetData(string), logError))
        return false;
    // Take over the bytes with the CBByteArray
    if (NOT CBInitByteArrayWithData(CBGetByteArray(self), bytes.data, bytes.length, logError))
        return false;
    CBByteArrayReverseBytes(CBGetByteArray(self)); // CBBigInt is in little-endian. Conversion needed to make bitcoin address the right way.
    return true;
}
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);
}
Exemplo n.º 19
0
CBMerkleNode * CBBuildMerkleTree(CBByteArray ** hashes, uint32_t numHashes){
	CBMerkleNode * level = malloc(numHashes * sizeof(*level)); // Nodes on a level of the tree for processing.
	// Create nodes from the CBByteArray hashes
	for (uint32_t x = 0; x < numHashes; x++) {
		memcpy(level[x].hash, CBByteArrayGetData(hashes[x]), 32);
		level[x].left = NULL;
		level[x].right = NULL;
	}
	// Build each level upwards to the root
	uint8_t hash[32];
	uint8_t cat[64];
	CBMerkleNode * nextLevel = malloc((numHashes + 1)/2 * sizeof(*level));
	for (uint32_t x = 0;;) {
		nextLevel[x/2].left = level + x;
		if (x == numHashes - 1)
			nextLevel[x/2].right = level + x;
		else
			nextLevel[x/2].right = level + x + 1;
		memcpy(cat, nextLevel[x/2].left->hash, 32);
		memcpy(cat + 32, nextLevel[x/2].right->hash, 32);
		// Double SHA256
		CBSha256(cat, 64, hash);
		CBSha256(hash, 32, nextLevel[x/2].hash);
		x += 2;
		if (x >= numHashes) {
			// Finished level
			if (x > numHashes)
				// The number of hashes was odd. Increment to even
				numHashes++;
			numHashes /= 2;
			// Move to next level
			level = nextLevel;
			if (numHashes == 1)
				// Done, got the single root hash
				break;
			x = 0;
			nextLevel = malloc((numHashes + 1)/2 * sizeof(*level));
		}
	}
	// Return last level which contains only the root node.
	return level;
}
bool CBBlockChainStorageSaveBlock(void * validator, void * block, uint8_t branch, uint32_t blockIndex){
	CBFullValidator * validatorObj = validator;
	CBBlock * blockObj = block;
	// Write the block data
	CB_BLOCK_KEY[2] = branch;
	CBInt32ToArray(CB_BLOCK_KEY, 3, blockIndex);
	uint8_t * dataParts[2] = {CBBlockGetHash(blockObj), CBByteArrayGetData(CBGetMessage(blockObj)->bytes)};
	uint32_t dataSizes[2] = {20, CBGetMessage(blockObj)->bytes->length};
	if (NOT CBDatabaseWriteConcatenatedValue((CBDatabase *)validatorObj->storage, CB_BLOCK_KEY, 2, dataParts, dataSizes)) {
		CBLogError("Could not write a block to the block-chain database.");
		return false;
	}
	// Write to the block hash index
	memcpy(CB_BLOCK_HASH_INDEX_KEY + 2, CBBlockGetHash(blockObj), 20);
	CB_DATA_ARRAY[CB_BLOCK_HASH_REF_BRANCH] = branch;
	CBInt32ToArray(CB_DATA_ARRAY, CB_BLOCK_HASH_REF_INDEX, blockIndex);
	if (NOT CBDatabaseWriteValue((CBDatabase *)validatorObj->storage, CB_BLOCK_HASH_INDEX_KEY, CB_DATA_ARRAY, 5)) {
		CBLogError("Could not write a block hash to the block-chain database block hash index.");
		return false;
	}
	return true;
}
Exemplo n.º 21
0
bool CBAddressStorageDeleteAddress(uint64_t iself, void * address){
	CBAddressStore * self = (CBAddressStore *)iself;
	CBNetworkAddress * addrObj = address;
	memcpy(CB_ADDRESS_KEY + 1, CBByteArrayGetData(addrObj->ip), 16);
	CBInt16ToArray(CB_ADDRESS_KEY, 17, addrObj->port);
	// Remove address
	if (NOT CBDatabaseRemoveValue(CBGetDatabase(self), CB_ADDRESS_KEY)) {
		CBLogError("Could not remove an address from storage.");
		return false;
	}
	// Decrease number of addresses
	CBInt32ToArray(CB_DATA_ARRAY, 0, --self->numAddresses);
	if (NOT CBDatabaseWriteValue(CBGetDatabase(self), CB_ADDR_NUM_KEY, CB_DATA_ARRAY, 4)) {
		CBLogError("Could not write the new number of addresses to storage.");
		return false;
	}
	// Commit changes
	if (NOT CBDatabaseCommit(CBGetDatabase(self))) {
		CBLogError("Could not commit the removal of a network address.");
		return false;
	}
	return true;
}
Exemplo n.º 22
0
CBGetHashReturn CBTransactionGetInputHashForSignature(void * vself, CBByteArray * prevOutSubScript, uint32_t input, CBSignType signType, uint8_t * hash){
	CBTransaction * self= vself;
	if (self->inputNum < input + 1) {
		CBLogError("Receiving transaction hash to sign cannot be done for because the input index goes past the number of inputs.");
		return CB_TX_HASH_BAD;
	}
	uint8_t last5Bits = (signType & 0x1f); // For some reason this is what the C++ client does.
	CBVarInt prevOutputSubScriptVarInt = CBVarIntFromUInt64(prevOutSubScript->length);
	uint32_t sizeOfData = 12 + prevOutSubScript->length + prevOutputSubScriptVarInt.size; // Version, lock time and the sign type make up 12 bytes.
	if (signType & CB_SIGHASH_ANYONECANPAY) {
		sizeOfData += 41; // Just this one input. 32 bytes for outPointerHash, 4 for outPointerIndex, 4 for sequence and one for the *inputNum* var int
	}else{
		sizeOfData += CBVarIntSizeOf(self->inputNum) + self->inputNum * 41 - 1; // All inputs with 1 byte var int except one.
	}
	if (last5Bits == CB_SIGHASH_NONE){
		sizeOfData++; // Just for the CBVarInt and no outputs.
	}else if ((signType & 0x1f) == CB_SIGHASH_SINGLE){
		if (self->outputNum < input + 1) {
			CBLogError("Receiving transaction hash to sign cannot be done for CB_SIGHASH_SINGLE because there are not enough outputs.");
			return CB_TX_HASH_BAD;
		}
		sizeOfData += CBVarIntSizeOf(input + 1) + input * 9; // For outputs up to the input index
		// The size for the output at the input index.
		uint32_t len = CBGetByteArray(self->outputs[input]->scriptObject)->length;
		sizeOfData += 8 + CBVarIntSizeOf(len) + len;
	}else{ // All outputs. Default to SIGHASH_ALL
		sizeOfData += CBVarIntSizeOf(self->outputNum);
		for (uint32_t x = 0; x < self->outputNum; x++) {
			uint32_t len = CBGetByteArray(self->outputs[x]->scriptObject)->length;
			sizeOfData += 8 + CBVarIntSizeOf(len) + len;
		}
	}
	CBByteArray * data = CBNewByteArrayOfSize(sizeOfData);
	if (NOT data)
		return CB_TX_HASH_ERR;
	CBByteArraySetInt32(data, 0, self->version);
	// Copy input data. Scripts are not copied for the inputs.
	uint32_t cursor;
	if (signType & CB_SIGHASH_ANYONECANPAY) {
		CBVarIntEncode(data, 4, CBVarIntFromUInt64(1)); // Only the input the signature is for.
		CBByteArrayCopyByteArray(data, 5, self->inputs[input]->prevOut.hash);
		CBByteArraySetInt32(data, 37, self->inputs[input]->prevOut.index);
		// Add prevOutSubScript
		CBVarIntEncode(data, 41, prevOutputSubScriptVarInt);
		cursor = 41 + prevOutputSubScriptVarInt.size;
		CBByteArrayCopyByteArray(data, cursor, prevOutSubScript);
		cursor += prevOutSubScript->length;
		CBByteArraySetInt32(data, cursor, self->inputs[input]->sequence);
		cursor += 4;
	}else{
		CBVarInt inputNum = CBVarIntFromUInt64(self->inputNum);
		CBVarIntEncode(data, 4, inputNum);
		cursor = 4 + inputNum.size;
		for (uint32_t x = 0; x < self->inputNum; x++) {
			CBByteArrayCopyByteArray(data, cursor, self->inputs[x]->prevOut.hash);
			cursor += 32;
			CBByteArraySetInt32(data, cursor, self->inputs[x]->prevOut.index);
			cursor += 4;
			// Add prevOutSubScript if the input is for the signature.
			if (x == input) {
				CBVarIntEncode(data, cursor, prevOutputSubScriptVarInt);
				cursor += prevOutputSubScriptVarInt.size;
				CBByteArrayCopyByteArray(data, cursor, prevOutSubScript);
				cursor += prevOutSubScript->length;
			}else{
				CBVarIntEncode(data, cursor, CBVarIntFromUInt64(0));
				cursor++;
			}
			if ((signType == CB_SIGHASH_NONE || signType == CB_SIGHASH_SINGLE) && x != input) {
				CBByteArraySetInt32(data, cursor, 0);
			}
			else // SIGHASH_ALL or input index for signing sequence
				CBByteArraySetInt32(data, cursor, self->inputs[x]->sequence);
			cursor += 4;
		}
	}
	// Copy output data
	if (last5Bits == CB_SIGHASH_NONE){
		CBVarInt varInt = CBVarIntFromUInt64(0);
		CBVarIntEncode(data, cursor, varInt);
		cursor++;
	}else if (last5Bits == CB_SIGHASH_SINGLE){
		CBVarInt varInt = CBVarIntFromUInt64(input + 1);
		CBVarIntEncode(data, cursor, varInt);
		cursor += varInt.size;
		for (uint32_t x = 0; x < input; x++) {
			CBByteArraySetInt64(data, cursor, CB_OUTPUT_VALUE_MINUS_ONE);
			cursor += 8;
			CBVarIntEncode(data, cursor, CBVarIntFromUInt64(0));
			cursor++;
		}
		CBByteArraySetInt64(data, cursor, self->outputs[input]->value);
		cursor += 8;
		varInt = CBVarIntFromUInt64(CBGetByteArray(self->outputs[input]->scriptObject)->length);
		CBVarIntEncode(data, cursor, varInt);
		cursor += varInt.size;
		CBByteArrayCopyByteArray(data, cursor, CBGetByteArray(self->outputs[input]->scriptObject));
		cursor += varInt.val;
	}else{ // SIGHASH_ALL
		CBVarInt varInt = CBVarIntFromUInt64(self->outputNum);
		CBVarIntEncode(data, cursor, varInt);
		cursor += varInt.size;
		for (uint32_t x = 0; x < self->outputNum; x++) {
			CBByteArraySetInt64(data, cursor, self->outputs[x]->value);
			cursor += 8;
			varInt = CBVarIntFromUInt64(CBGetByteArray(self->outputs[x]->scriptObject)->length);
			CBVarIntEncode(data, cursor, varInt);
			cursor += varInt.size;
			CBByteArrayCopyByteArray(data, cursor, CBGetByteArray(self->outputs[x]->scriptObject));
			cursor += varInt.val;
		}
	}
	// Set lockTime
	CBByteArraySetInt32(data, cursor, self->lockTime);
	CBByteArraySetInt32(data, cursor + 4, signType);
	assert(sizeOfData == cursor + 8); // Must always be like this
	uint8_t firstHash[32];
	CBSha256(CBByteArrayGetData(data), sizeOfData, firstHash);
	CBSha256(firstHash, 32, hash);
	return CB_TX_HASH_OK;
}
Exemplo n.º 23
0
void CBTransactionCalculateHash(CBTransaction * self, uint8_t * hash){
	uint8_t * data = CBByteArrayGetData(CBGetMessage(self)->bytes);
	uint8_t hash2[32];
	CBSha256(data, CBGetMessage(self)->bytes->length, hash2);
	CBSha256(hash2, 32, hash);
}
Exemplo n.º 24
0
int main(){
	unsigned int s = (unsigned int)time(NULL);
	s = 1337544566;
	printf("Session = %ui\n",s);
	srand(s);
	// Test deserialisation of real alert
	uint8_t data[188] = {
		0x73, // Length of payload
		0x01,0x00,0x00,0x00, // Version 1
		0x37,0x66,0x40,0x4F,0x00,0x00,0x00,0x00, // Relay until 1329620535
		0xB3,0x05,0x43,0x4F,0x00,0x00,0x00,0x00, // Expires at 1329792435
		0xF2,0x03,0x00,0x00, // ID 1010
		0xF1,0x03,0x00,0x00, // Cancel < 1009
		0x00, // No more IDs
		0x10,0x27,0x00,0x00, // Min version 10000
		0x48,0xee,0x00,0x00, // Max version 61000
		0x00, // No user agents
		0x64,0x00,0x00,0x00, // Priority 100
		0x00, // Empty hidden comment
		0x46, // Displayed comment is 70 characters long
		// "See bitcoin.org/feb20 if you have trouble connecting after 20 February"
		0x53,0x65,0x65,0x20,0x62,0x69,0x74,0x63,0x6F,0x69,0x6E,0x2E,0x6F,0x72,0x67,0x2F,0x66,0x65,0x62,0x32,0x30,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x20,0x68,0x61,0x76,0x65,0x20,0x74,0x72,0x6F,0x75,0x62,0x6C,0x65,0x20,0x63,0x6F,0x6E,0x6E,0x65,0x63,0x74,0x69,0x6E,0x67,0x20,0x61,0x66,0x74,0x65,0x72,0x20,0x32,0x30,0x20,0x46,0x65,0x62,0x72,0x75,0x61,0x72,0x79,
		0x00, // No reserved
		// Signature
		0x47, // Signature is 71 bytes long
		0x30,0x45,0x02,0x21,0x00,0x83,0x89,0xdf,0x45,0xF0,0x70,0x3F,0x39,0xEC,0x8C,0x1C,0xC4,0x2C,0x13,0x81,0x0F,0xFC,0xAE,0x14,0x99,0x5B,0xB6,0x48,0x34,0x02,0x19,0xE3,0x53,0xB6,0x3B,0x53,0xEB,0x02,0x20,0x09,0xEC,0x65,0xE1,0xC1,0xAA,0xEE,0xC1,0xFD,0x33,0x4C,0x6B,0x68,0x4B,0xDE,0x2B,0x3F,0x57,0x30,0x60,0xD5,0xb7,0x0C,0x3A,0x46,0x72,0x33,0x26,0xE4,0xE8,0xA4,0xF1
	};
	CBByteArray * bytes = CBNewByteArrayWithDataCopy(data, 188, logError);
	CBAlert * alert = CBNewAlertFromData(bytes, logError);
	if(CBAlertDeserialise(alert) != 188){
		printf("DESERIALISATION LEN FAIL\n");
		return 1;
	}
	if (alert->version != 1) {
		printf("DESERIALISATION VERSION FAIL\n");
		return 1;
	}
	if (alert->relayUntil != 1329620535) {
		printf("DESERIALISATION RELAY UNTIL FAIL\n");
		return 1;
	}
	if (alert->expiration != 1329792435) {
		printf("DESERIALISATION EXPIRATION FAIL\n");
		return 1;
	}
	if (alert->ID != 1010) {
		printf("DESERIALISATION ID FAIL\n");
		return 1;
	}
	if (alert->cancel != 1009) {
		printf("DESERIALISATION CANCEL FAIL\n");
		return 1;
	}
	if (alert->setCancelNum != 0) {
		printf("DESERIALISATION SET CANCEL NUM FAIL\n");
		return 1;
	}
	if (alert->setCancel != NULL) {
		printf("DESERIALISATION SET CANCEL FAIL\n");
		return 1;
	}
	if (alert->minVer != 10000) {
		printf("DESERIALISATION MIN VERSION FAIL\n");
		return 1;
	}
	if (alert->maxVer != 61000) {
		printf("DESERIALISATION MAX VERSION FAIL\n");
		return 1;
	}
	if (alert->userAgentNum != 0) {
		printf("DESERIALISATION USER AGENT NUM FAIL\n");
		return 1;
	}
	if (alert->userAgents != NULL) {
		printf("DESERIALISATION USER AGENTS FAIL\n");
		return 1;
	}
	if (alert->priority != 100) {
		printf("DESERIALISATION PRIORITY FAIL\n");
		return 1;
	}
	if (alert->hiddenComment != NULL) {
		printf("DESERIALISATION HIDDEN COMMENT FAIL\n");
		return 1;
	}
	if (memcmp(CBByteArrayGetData(alert->displayedComment),"See bitcoin.org/feb20 if you have trouble connecting after 20 February",70)) {
		printf("DESERIALISATION DISPLAYED COMMENT FAIL\n0x");
		char * d = (char *)CBByteArrayGetData(alert->displayedComment);
		for (int x = 0; x < 70; x++) {
			printf("%c",d[x]);
		}
		printf("\n!=\nSee bitcoin.org/feb20 if you have trouble connecting after 20 February\n");
		return 1;
	}
	if (alert->reserved != NULL) {
		printf("DESERIALISATION RESERVED FAIL\n");
		return 1;
	}
	// Check signature
	CBByteArray * payload = CBAlertGetPayload(alert);
	uint8_t hash1[32];
	CBSha256(CBByteArrayGetData(payload),payload->length,hash1);
	uint8_t hash2[32];
	CBSha256(hash1, 32,hash2);
	if (NOT CBEcdsaVerify(CBByteArrayGetData(alert->signature),alert->signature->length,hash2,(uint8_t [65]){0x04,0xFC,0x97,0x02,0x84,0x78,0x40,0xAA,0xF1,0x95,0xDE,0x84,0x42,0xEB,0xEC,0xED,0xF5,0xB0,0x95,0xCD,0xBB,0x9B,0xC7,0x16,0xBD,0xA9,0x11,0x09,0x71,0xB2,0x8A,0x49,0xE0,0xEA,0xD8,0x56,0x4F,0xF0,0xDB,0x22,0x20,0x9E,0x03,0x74,0x78,0x2C,0x09,0x3B,0xB8,0x99,0x69,0x2D,0x52,0x4E,0x9D,0x6A,0x69,0x56,0xE7,0xC5,0xEC,0xBC,0xD6,0x82,0x84},65)) {
		printf("DESERIALISATION SIG FAIL\n");
		return 1;
	}
	CBReleaseObject(payload);
	// Test serialisation
	memset(CBByteArrayGetData(bytes), 0, 188);
	CBReleaseObject(alert->displayedComment);
	alert->displayedComment = CBNewByteArrayWithDataCopy((uint8_t *)"See bitcoin.org/feb20 if you have trouble connecting after 20 February", 70, logError);
	CBReleaseObject(alert->signature);
	alert->signature = CBNewByteArrayWithDataCopy((uint8_t []){0x30,0x45,0x02,0x21,0x00,0x83,0x89,0xdf,0x45,0xF0,0x70,0x3F,0x39,0xEC,0x8C,0x1C,0xC4,0x2C,0x13,0x81,0x0F,0xFC,0xAE,0x14,0x99,0x5B,0xB6,0x48,0x34,0x02,0x19,0xE3,0x53,0xB6,0x3B,0x53,0xEB,0x02,0x20,0x09,0xEC,0x65,0xE1,0xC1,0xAA,0xEE,0xC1,0xFD,0x33,0x4C,0x6B,0x68,0x4B,0xDE,0x2B,0x3F,0x57,0x30,0x60,0xD5,0xb7,0x0C,0x3A,0x46,0x72,0x33,0x26,0xE4,0xE8,0xA4,0xF1}, 71, logError);
	CBAlertSerialisePayload(alert);
	if(CBAlertSerialiseSignature(alert, 116) != 188){
		printf("SERIALISATION LEN FAIL\n");
		return 1;
	}
	if (memcmp(data, CBByteArrayGetData(bytes), 188)) {
		printf("SERIALISATION FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(bytes);
		for (int x = 0; x < 188; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		for (int x = 0; x < 188; x++) {
			printf("%.2X",data[x]);
		}
		return 1;
	}
	CBReleaseObject(alert);
	CBReleaseObject(bytes);
	return 0;
}
Exemplo n.º 25
0
void CBBlockCalculateHash(CBBlock * self, uint8_t * hash){
	uint8_t * headerData = CBByteArrayGetData(CBGetMessage(self)->bytes);
	uint8_t hash2[32];
	CBSha256(headerData, 80, hash2);
	CBSha256(hash2, 32, hash);
}
Exemplo n.º 26
0
bool BEInitFullNode(BEFullNode * self,void (*onErrorReceived)(CBError error,char *,...)){
	if (NOT CBInitNetworkCommunicator(CBGetNetworkCommunicator(self), onErrorReceived))
		return false;
	// Set network communicator fields.
	CBGetNetworkCommunicator(self)->blockHeight = 0;
	CBGetNetworkCommunicator(self)->callbackHandler = self;
	CBGetNetworkCommunicator(self)->flags = CB_NETWORK_COMMUNICATOR_AUTO_DISCOVERY | CB_NETWORK_COMMUNICATOR_AUTO_HANDSHAKE | CB_NETWORK_COMMUNICATOR_AUTO_PING;
	CBGetNetworkCommunicator(self)->version = CB_PONG_VERSION;
	CBNetworkCommunicatorSetAlternativeMessages(CBGetNetworkCommunicator(self), NULL, NULL);
	// Find home directory.
	const char * homeDir;
	struct passwd * pwd = getpwuid(getuid());
	if (NOT pwd)
		return false;
	homeDir = pwd->pw_dir;
	unsigned long homeLen = strlen(homeDir);
	// Open or create a new address store
	unsigned long dataDirLen = strlen(BE_DATA_DIRECTORY);
	char * addressFilePath = malloc(homeLen + dataDirLen + strlen(BE_ADDRESS_DATA_FILE) + 1);
	memcpy(addressFilePath, homeDir, homeLen);
	memcpy(addressFilePath + homeLen, BE_DATA_DIRECTORY, strlen(BE_DATA_DIRECTORY));
	strcpy(addressFilePath + homeLen + dataDirLen, BE_ADDRESS_DATA_FILE);
	self->addressFile = fopen(addressFilePath, "rb+");
	if (self->addressFile) {
		// The address store exists.
		free(addressFilePath);
		// Get the file length
		fseek(self->addressFile, 0, SEEK_END);
		unsigned long fileLen = ftell(self->addressFile);
		fseek(self->addressFile, 0, SEEK_SET);
		// Read file into a CBByteArray
		CBByteArray * buffer = CBNewByteArrayOfSize((uint32_t)fileLen, onErrorReceived);
		if (NOT buffer) {
			fclose(self->addressFile);
			return false;
		}
		if(fread(CBByteArrayGetData(buffer), fileLen, 1, self->addressFile) != fileLen){
			CBReleaseObject(buffer);
			fclose(self->addressFile);
			return false;
		}
		// Create the CBAddressManager
		CBGetNetworkCommunicator(self)->addresses = CBNewAddressManagerFromData(buffer, onErrorReceived, BEFullNodeOnBadTime);
		CBReleaseObject(buffer);
		if (NOT CBAddressManagerDeserialise(CBGetNetworkCommunicator(self)->addresses)){
			fclose(self->addressFile);
			CBReleaseObject(CBGetNetworkCommunicator(self)->addresses);
			onErrorReceived(CB_ERROR_INIT_FAIL,"There was an error when deserialising the CBAddressManager for the BEFullNode.");
			return false;
		}
	}else{
		// The address store does not exist
		CBGetNetworkCommunicator(self)->addresses = CBNewAddressManager(onErrorReceived, BEFullNodeOnBadTime);
		if (NOT CBGetNetworkCommunicator(self)->addresses)
			return false;
		// Create the file
		self->addressFile = fopen(addressFilePath, "wb");
		free(addressFilePath);
		if (NOT self->addressFile){
			CBReleaseObject(CBGetNetworkCommunicator(self)->addresses);
			return false;
		}
	}
	// Create block validator
	
	return true;
}
Exemplo n.º 27
0
int main(){
	printf("OpenSSL version: %s\n", OPENSSL_VERSION_TEXT);
	printf("Enter the number of keys: ");
	fflush(stdout);
	char stringMatch[31];
	getLine(stringMatch);
	unsigned long int i = strtol(stringMatch, NULL, 0);
	printf("Enter a string of text for the key (30 max): ");
	fflush(stdout);
	getLine(stringMatch);
	printf("Waiting for entropy... Move the cursor around...\n");
	fflush(stdout);
	char entropy[32];
	FILE * f = fopen("/dev/random", "r");
	if (fread(entropy, 32, 1, f) != 1){
		printf("FAILURING GETTING ENTROPY!");
		return 1;
	}
	RAND_add(entropy, 32, 32);
	fclose(f);
	printf("Making %lu addresses for \"%s\"\n\n", i, stringMatch);
	EC_KEY * key = EC_KEY_new_by_curve_name(NID_secp256k1);
	uint8_t * pubKey = NULL;
	int pubSize = 0;
	uint8_t * privKey = NULL;
	int privSize = 0;
	uint8_t * shaHash = malloc(32);
	uint8_t * ripemdHash = malloc(20);
	for (unsigned int x = 0; x < i;) {
		if(! EC_KEY_generate_key(key)){
			printf("GENERATE KEY FAIL\n"); 
			return 1;
		}
		int pubSizeNew = i2o_ECPublicKey(key, NULL);
		if(! pubSizeNew){
			printf("PUB KEY TO DATA ZERO\n"); 
			return 1;
		}
		if (pubSizeNew != pubSize) {
			pubSize = pubSizeNew;
			pubKey = realloc(pubKey, pubSize);
		}
		uint8_t * pubKey2 = pubKey;
		if(i2o_ECPublicKey(key, &pubKey2) != pubSize){
			printf("PUB KEY TO DATA FAIL\n");
			return 1;
		}
		SHA256(pubKey, pubSize, shaHash);
		RIPEMD160(shaHash, 32, ripemdHash);
		CBAddress * address = CBNewAddressFromRIPEMD160Hash(ripemdHash, CB_PRODUCTION_NETWORK_BYTE, false, err);
		CBByteArray * string = CBChecksumBytesGetString(CBGetChecksumBytes(address));
		CBReleaseObject(address);
		bool match = true;
		uint8_t offset = 1;
		size_t matchSize = strlen(stringMatch);
		for (uint8_t y = 0; y < matchSize;) {
			char other = islower(stringMatch[y]) ? toupper(stringMatch[y]) : (isupper(stringMatch[y])? tolower(stringMatch[y]) : '\0');
			if (CBByteArrayGetByte(string, y+offset) != stringMatch[y] && CBByteArrayGetByte(string, y+offset) != other) {
				offset++;
				y = 0;
				if (string->length < matchSize + offset) {
					match = false;
					break;
				}
			}else y++;
		}
		if (match) {
			// Get private key
			const BIGNUM * privKeyNum = EC_KEY_get0_private_key(key);
			if (! privKeyNum) {
				printf("PRIV KEY TO BN FAIL\n");
			}
			int privSizeNew = BN_num_bytes(privKeyNum);
			if (privSizeNew != privSize) {
				privSize = privSizeNew;
				privKey = realloc(privKey, privSize);
			}
			int res = BN_bn2bin(privKeyNum, privKey);
			if (res != privSize) {
				printf("PRIV KEY TO DATA FAIL\n");
			}
			// Print data to stdout
			printf("Private key (hex): ");
			for (int x = 0; x < privSize; x++) {
				printf(" %.2X", privKey[x]);
			}
			printf("\nPublic key (hex): ");
			for (int x = 0; x < pubSize; x++) {
				printf(" %.2X", pubKey[x]);
			}
			printf("\nAddress (base-58): %s\n\n", CBByteArrayGetData(string));
			x++; // Move to next
		}
		CBReleaseObject(string);
	}
	free(shaHash);
	free(ripemdHash);
	EC_KEY_free(key);
	return 0;
}
Exemplo n.º 28
0
void checkKey(CBHDKey * key, uint8_t x, uint8_t y){
	// Check version bytes
	if (key->versionBytes != CB_HD_KEY_VERSION_PROD_PRIVATE) {
		printf("VERSION BYTES FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	// Check address
	CBAddress * address = CBNewAddressFromRIPEMD160Hash(CBHDKeyGetHash(key), CB_NETWORK_PRODUCTION, false);
	CBByteArray * str = CBChecksumBytesGetString(CBGetChecksumBytes(address));
	CBReleaseObject(address);
	if (memcmp(CBByteArrayGetData(str), testVectors[x][y].addr, 34) != 0) {
		printf("ADDR FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	CBReleaseObject(str);
	// Check WIF
	CBWIF * wif = CBHDKeyGetWIF(key);
	str = CBChecksumBytesGetString(CBGetChecksumBytes(wif));
	CBReleaseObject(wif);
	if (memcmp(CBByteArrayGetData(str), testVectors[x][y].WIF, 52) != 0) {
		printf("WIF FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	CBReleaseObject(str);
	// Check chain code
	if (memcmp(key->chainCode, testVectors[x][y].chainCode, 32) != 0) {
		printf("CHAIN CODE FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	// Check child ID
	if (memcmp(&key->childID, &testVectors[x][y].childID, sizeof(key->childID)) != 0) {
		printf("CHILD ID FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	// Check depth
	if (key->depth != y) {
		printf("DEPTH FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	// Check serialisation of private key
	uint8_t * keyData = malloc(82);
	CBHDKeySerialise(key, keyData);
	CBChecksumBytes * checksumBytes = CBNewChecksumBytesFromBytes(keyData, 82, false);
	str = CBChecksumBytesGetString(checksumBytes);
	CBReleaseObject(checksumBytes);
	if (memcmp(CBByteArrayGetData(str), testVectors[x][y].privString, 111) != 0) {
		printf("PRIVATE KEY STRING FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	CBReleaseObject(str);
	// Check serialisation of public key
	key->versionBytes = CB_HD_KEY_VERSION_PROD_PUBLIC;
	keyData = malloc(82);
	CBHDKeySerialise(key, keyData);
	checksumBytes = CBNewChecksumBytesFromBytes(keyData, 82, false);
	str = CBChecksumBytesGetString(checksumBytes);
	CBReleaseObject(checksumBytes);
	if (memcmp(CBByteArrayGetData(str), testVectors[x][y].pubString, 111) != 0) {
		printf("PUBLIC KEY STRING FAIL AT %u - %u\n", x, y);
		exit(EXIT_FAILURE);
	}
	CBReleaseObject(str);
	// Make private again
	key->versionBytes = CB_HD_KEY_VERSION_PROD_PRIVATE;
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
int main(){
	unsigned int s = (unsigned int)time(NULL);
	s = 1337544566;
	printf("Session = %ui\n",s);
	srand(s);
	// Test genesis block
	CBByteArray * genesisMerkleRoot = CBNewByteArrayWithDataCopy((uint8_t []){0x3B,0xA3,0xED,0xFD,0x7A,0x7B,0x12,0xB2,0x7A,0xC7,0x2C,0x3E,0x67,0x76,0x8F,0x61,0x7F,0xC8,0x1B,0xC3,0x88,0x8A,0x51,0x32,0x3A,0x9F,0xB8,0xAA,0x4B,0x1E,0x5E,0x4A}, 32, onErrorReceived);
	CBByteArray * genesisInScript = CBNewByteArrayWithDataCopy((uint8_t [77]){0x04,0xFF,0xFF,0x00,0x1D,0x01,0x04,0x45,0x54,0x68,0x65,0x20,0x54,0x69,0x6D,0x65,0x73,0x20,0x30,0x33,0x2F,0x4A,0x61,0x6E,0x2F,0x32,0x30,0x30,0x39,0x20,0x43,0x68,0x61,0x6E,0x63,0x65,0x6C,0x6C,0x6F,0x72,0x20,0x6F,0x6E,0x20,0x62,0x72,0x69,0x6E,0x6B,0x20,0x6F,0x66,0x20,0x73,0x65,0x63,0x6F,0x6E,0x64,0x20,0x62,0x61,0x69,0x6C,0x6F,0x75,0x74,0x20,0x66,0x6F,0x72,0x20,0x62,0x61,0x6E,0x6B,0x73}, 77, onErrorReceived);
	CBByteArray * genesisOutScript = CBNewByteArrayWithDataCopy((uint8_t [67]){0x41,0x04,0x67,0x8A,0xFD,0xB0,0xFE,0x55,0x48,0x27,0x19,0x67,0xF1,0xA6,0x71,0x30,0xB7,0x10,0x5C,0xD6,0xA8,0x28,0xE0,0x39,0x09,0xA6,0x79,0x62,0xE0,0xEA,0x1F,0x61,0xDE,0xB6,0x49,0xF6,0xBC,0x3F,0x4C,0xEF,0x38,0xC4,0xF3,0x55,0x04,0xE5,0x1E,0xC1,0x12,0xDE,0x5C,0x38,0x4D,0xF7,0xBA,0x0B,0x8D,0x57,0x8A,0x4C,0x70,0x2B,0x6B,0xF1,0x1D,0x5F,0xAC}, 67, onErrorReceived);
	// Test hash
	CBBlock * genesisBlock = CBNewBlockGenesis(onErrorReceived);
	uint8_t calcHash[32];
	CBBlockCalculateHash(genesisBlock,calcHash);
	if(memcmp(genesisBlock->hash, calcHash,32)){
		printf("GENESIS BLOCK HASH FAIL\n0x");
		uint8_t * d = genesisBlock->hash;
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = calcHash;
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	// Test deserialised data
	if (genesisBlock->version != 1) {
		printf("GENESIS BLOCK VERSION FAIL\n");
		return 1;
	}
	for (int x = 0; x < 32; x++) {
		if(CBByteArrayGetByte(genesisBlock->prevBlockHash, x) != 0){
			printf("GENESIS BLOCK PREV FAIL\n");
			return 1;
		}
	}
	if (CBByteArrayCompare(genesisBlock->merkleRoot, genesisMerkleRoot)) {
		printf("GENESIS BLOCK MERKLE ROOT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisBlock->merkleRoot);
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisMerkleRoot);
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	if (genesisBlock->time != 1231006505) {
		printf("GENESIS BLOCK TIME FAIL\n0x");
		return 1;
	}
	if (genesisBlock->target != 0x1D00FFFF) {
		printf("GENESIS BLOCK DIFFICULTY FAIL\n0x");
		return 1;
	}
	if (genesisBlock->nonce != 2083236893) {
		printf("GENESIS BLOCK DIFFICULTY FAIL\n0x");
		return 1;
	}
	if (genesisBlock->transactionNum != 1) {
		printf("GENESIS BLOCK TRANSACTION NUM FAIL\n0x");
		return 1;
	}
	CBTransaction * genesisCoinBase = genesisBlock->transactions[0];
	if (genesisCoinBase->inputNum != 1) {
		printf("GENESIS BLOCK TRANSACTION INPUT NUM FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->outputNum != 1) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT NUM FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->version != 1) {
		printf("GENESIS BLOCK TRANSACTION VERSION FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->lockTime != 0) {
		printf("GENESIS BLOCK TRANSACTION LOCK TIME FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->inputs[0]->scriptObject->length != 0x4D) {
		printf("GENESIS BLOCK TRANSACTION INPUT SCRIPT LENGTH FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->outputs[0]->scriptObject->length != 0x43) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT SCRIPT LENGTH FAIL\n0x");
		return 1;
	}
	for (int x = 0; x < 32; x++) {
		if(CBByteArrayGetByte(genesisCoinBase->inputs[0]->prevOut.hash, x) != 0){
			printf("GENESIS BLOCK TRANSACTION INPUT OUT POINTER HASH FAIL\n");
			return 1;
		}
	}
	if (genesisCoinBase->inputs[0]->prevOut.index != 0xFFFFFFFF) {
		printf("GENESIS BLOCK TRANSACTION INPUT OUT POINTER INDEX FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->inputs[0]->sequence != CB_TRANSACTION_INPUT_FINAL) {
		printf("GENESIS BLOCK TRANSACTION INPUT SEQUENCE FAIL\n0x");
		return 1;
	}
	if (CBByteArrayCompare(genesisCoinBase->inputs[0]->scriptObject, genesisInScript)) {
		printf("GENESIS BLOCK IN SCRIPT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisCoinBase->inputs[0]->scriptObject);
		for (int x = 0; x < genesisCoinBase->inputs[0]->scriptObject->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisInScript);
		for (int x = 0; x < genesisInScript->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	if (genesisCoinBase->outputs[0]->value != 5000000000) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT VALUE FAIL\n0x");
		return 1;
	}
	if (CBByteArrayCompare(genesisCoinBase->outputs[0]->scriptObject, genesisOutScript)) {
		printf("GENESIS BLOCK OUT SCRIPT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisCoinBase->outputs[0]->scriptObject);
		for (int x = 0; x < genesisCoinBase->outputs[0]->scriptObject->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisOutScript);
		for (int x = 0; x < genesisOutScript->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	// Test serialisation into genesis block
	CBBlock * block = CBNewBlock(onErrorReceived);
	block->version = 1;
	uint8_t * zeroHash = malloc(32);
	memset(zeroHash, 0, 32);
	block->prevBlockHash = CBNewByteArrayWithData(zeroHash, 32, onErrorReceived);
	block->merkleRoot = genesisMerkleRoot;
	block->target = 0x1D00FFFF;
	block->time = 1231006505;
	block->nonce = 2083236893;
	block->transactionNum = 1;
	block->transactions = malloc(sizeof(*block->transactions));
	block->transactions[0] = CBNewTransaction(0, 1, onErrorReceived);
	CBRetainObject(block->prevBlockHash); // Retain for the zero hash in the input
	CBTransactionTakeInput(block->transactions[0], CBNewTransactionInput(genesisInScript, CB_TRANSACTION_INPUT_FINAL, block->prevBlockHash, 0xFFFFFFFF, onErrorReceived));
	CBTransactionTakeOutput(block->transactions[0], CBNewTransactionOutput(5000000000, genesisOutScript, onErrorReceived));
	CBGetMessage(block)->bytes = CBNewByteArrayOfSize(CBGetMessage(genesisBlock)->bytes->length, onErrorReceived);
	CBBlockSerialise(block, true, true);
	if (CBByteArrayCompare(CBGetMessage(block)->bytes, CBGetMessage(genesisBlock)->bytes)) {
		printf("SERIALISATION TO GENESIS BLOCK FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(CBGetMessage(block)->bytes);
		for (int x = 0; x < CBGetMessage(block)->bytes->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(CBGetMessage(genesisBlock)->bytes);
		for (int x = 0; x < CBGetMessage(genesisBlock)->bytes->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	CBReleaseObject(genesisBlock);
	// ??? Add tests for non-genesis blocks
	return 0;
}