/*
This Work is under GPL provided with this work.

This work is based on the java implementation of the Kademlia protocol.
Kademlia: Peer-to-peer routing based on the XOR metric
Copyright (C) 2002  Petar Maymounkov [petar@post.harvard.edu]
http://kademlia.scs.cs.nyu.edu
and
This work is bassed on translation from Barry Dunne to C++
Copyright (C)2003 Barry Dunne (http://www.emule-project.net)
*/


#include "cygwin.h"
#include "cHash.h"
unsigned getBit(const uint8_t *HASH, unsigned bit) {{{
	if (bit > 127) return 0;
	int ulongNum = bit / 8;
	int shift = 7 - (bit % 8);
	return ((HASH[ulongNum] >> shift) & 1);
	}}}
void xor_128(uint8_t *a,const uint8_t *b) {{{
	for (int i=15; i>=0; i--) a[i] ^= b[i];
	}}}
void add_128(uint8_t *a,const uint8_t *b) {{{
	uint32_t sum = 0;
	for (int i=15; i>=0; i--) {
		sum += a[i];
		sum += b[i];
		a[i] = sum;
		sum = sum >> 8;
		}
	}}}
void shiftLeft(uint8_t *a, size_t bits) {{{
	if (bits == 0) return;
	if (0 == memcmp(a, null, 16)) return;		
	if (bits > 127) {{{
		memcpy(a, null, 16);
		return;
		}}}
	uint8_t result[16];
	bzero(result, 16);
	int indexShift = bits / 8;
	int shifted = 0;
	for (int i=15; i>=indexShift; i--) {
		uint16_t tmp= a[i];
		shifted += tmp << (bits % 8);
		result[i-indexShift] = shifted;
		shifted = shifted >> 8;
		}
	for (int j=0; j < 16; j++) a[j] = result[j];
	}}}
void setBitNumber(uint8_t *key, size_t bit, uint8_t val) {{{
	size_t ulongNum = bit / 8;
	size_t shift = 7 - (bit % 8);
        if (val == 0)	key[ulongNum] ^= (1 << shift);
	else		key[ulongNum] |= (1 << shift);
	}}}
void random(uint8_t *value, size_t numBits) {{{
	// Pad with random bytes (Not seeding based on time to allow multiple different ones to be created in quick succession)
	for (size_t i=numBits; i<128; i++) setBitNumber(value, i, (rand()%2));
	}}}
const uint8_t null    [16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
const uint8_t eins    [16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
const uint8_t acht    [16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8};

