60 const char*
HEX =
"0123456789abcdef";
85 trimSize = (int)min((uint32_t) (aSize *
sizeof(mp_limb_t)), size);
86 offset = aSize *
sizeof(mp_limb_t) - trimSize;
87 memcpy( ((
char*)key) + offset, buf, trimSize);
94 if ((base < 2) || (base > 16)) {
95 throw cRuntimeError(
"OverlayKey::OverlayKey(): Invalid base!");
101 for (uint32_t i=0; i<s.size(); i++) {
102 if ((s[i] >=
'0') && (s[i] <=
'9')) {
104 }
else if ((s[i] >=
'a') && (s[i] <=
'f')) {
106 }
else if ((s[i] >=
'A') & (s[i] <=
'F')) {
109 throw cRuntimeError(
"OverlayKey::OverlayKey(): "
110 "Invalid character in string!");
114 mpn_set_str ((mp_limb_t*)this->key, (
const unsigned char*)s.c_str(),
136 opp_error(
"OverlayKey::setKeyLength(): length must be <= %i "
137 "and setKeyLength() must not be called twice "
138 "with different length!", MAX_KEYLENGTH);
143 aSize = keyLength / (8*
sizeof(mp_limb_t)) +
144 (keyLength % (8*
sizeof(mp_limb_t))!=0 ? 1 : 0);
146 GMP_MSB_MASK = (keyLength % GMP_LIMB_BITS)
147 != 0 ? (((mp_limb_t)1 << (keyLength % GMP_LIMB_BITS))-1)
165 if ((base != 2) && (base != 16)) {
166 throw cRuntimeError(
"OverlayKey::OverlayKey(): Invalid base!");
170 return std::string(
"<unspec>");
172 char temp[MAX_KEYLENGTH+1];
176 for (
int i=(keyLength-1)/4; i>=0; i--, k++)
177 temp[k] =
HEX[this->getBitRange
181 return std::string((
const char*)temp);
182 }
else if (base==2) {
184 for (
int i=keyLength-1; i>=0; i-=1, k++)
185 temp[k] =
HEX[this->getBit(i)];
187 return std::string((
const char*)temp);
189 throw cRuntimeError(
"OverlayKey::OverlayKey(): Invalid base!");
194 mp_size_t last = mpn_get_str((
unsigned char*)temp, base,
195 (mp_limb_t*)this->key, aSize);
196 for (
int i=0; i<last; i++) {
197 temp[i] =
HEX[temp[i]];
200 return std::string((
const char*)temp);
214 memcpy( key, rhs.
key, aSize*
sizeof(mp_limb_t) );
221 return (*
this -= ONE);
235 return (*
this += ONE);
249 mpn_add_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.
key, aSize);
258 mpn_sub_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.
key, aSize);
283 return compareTo(compKey) < 0;
287 return compareTo(compKey) > 0;
291 return compareTo(compKey) <=0;
295 return compareTo(compKey) >=0;
299 return compareTo(compKey) ==0;
303 return compareTo(compKey) !=0;
310 for (uint32_t i=0; i<aSize; i++) {
311 result.
key[i] ^= rhs.
key[i];
321 for (uint32_t i=0; i<aSize; i++) {
322 result.
key[i] |= rhs.
key[i];
332 for (uint32_t i=0; i<aSize; i++) {
333 result.
key[i] &= rhs.
key[i];
343 for (uint32_t i=0; i<aSize; i++) {
344 result.
key[i] = ~key[i];
355 int i = num/GMP_LIMB_BITS;
357 num %= GMP_LIMB_BITS;
362 for (
int j=0; j<(int)aSize-i; j++) {
363 result.
key[j] = key[j+i];
365 mpn_rshift(result.
key,result.
key,aSize,num);
376 int i = num/GMP_LIMB_BITS;
378 num %= GMP_LIMB_BITS;
383 for (
int j=0; j<(int)aSize-i; j++) {
384 result.
key[j+i] = key[j];
386 mpn_lshift(result.
key,result.
key,aSize,num);
401 if (pos >= keyLength) {
402 throw cRuntimeError(
"OverlayKey::setBitAt(): "
403 "pos >= keyLength!");
407 digit = digit << (pos % GMP_LIMB_BITS);
410 key[pos / GMP_LIMB_BITS] |= digit;
413 key[pos / GMP_LIMB_BITS] &= ~digit;
426 int i = p / GMP_LIMB_BITS,
427 f = p % GMP_LIMB_BITS,
428 f2 = f + n - GMP_LIMB_BITS;
431 throw cRuntimeError(
"OverlayKey::get: Invalid range");
433 if (GMP_LIMB_BITS < 32) {
434 throw cRuntimeError(
"OverlayKey::get: GMP_LIMB_BITS too small!");
437 return ((key[i] >> f) |
438 (f2 > 0 ? (key[i+1] << (GMP_LIMB_BITS - f)) : 0)) &
439 (((uint32_t)(~0)) >> (GMP_LIMB_BITS - n));
445 uint8_t range = 32, length = getLength();
446 for (uint8_t i = 0; i < length; i += 32) {
447 if ((length - i) < 32) range = length - i;
448 result += (getBitRange(i, range) * pow(2.0, i));
458 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
459 mp_limb_t m = ((mp_limb_t)1 << j)-1;
465 newKey.
key[i] |= (rnd&m);
477 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
478 mp_limb_t m = ((mp_limb_t)1 << j)-1;
485 newKey.
key[i] |= (rnd&~m);
486 for (
int k=aSize-1; k!=i; k--) {
497 uint32_t bitsPerDigit)
const
499 if (compareTo(compKey) == 0)
return keyLength;
507 for (i=aSize-1; i>=0; --i) {
508 if (this->key[i] != compKey.
key[i]) {
510 mp_limb_t d = this->key[i] ^ compKey.
key[i];
511 if (msb) d <<= ( GMP_LIMB_BITS - (keyLength % GMP_LIMB_BITS) );
512 for (j = GMP_LIMB_BITS-1; d >>= 1; --j);
516 length += GMP_LIMB_BITS;
520 return length / bitsPerDigit;
528 while (i>=0 && key[i]==0) {
536 mp_limb_t j = key[i];
549 return (
size_t)key[0];
561 else if (keyA < keyB)
562 return ((*
this > keyA) && (*
this < keyB));
564 return ((*
this > keyA) || (*
this < keyB));
574 if ((keyA == keyB) && (*
this == keyA))
576 else if (keyA <= keyB)
577 return ((*
this > keyA) && (*
this <= keyB));
579 return ((*
this > keyA) || (*
this <= keyB));
589 if ((keyA == keyB) && (*
this == keyA))
591 else if (keyA <= keyB)
592 return ((*
this >= keyA) && (*
this < keyB));
594 return ((*
this >= keyA) || (*
this < keyB));
604 if ((keyA == keyB) && (*
this == keyA))
606 else if (keyA <= keyB)
607 return ((*
this >= keyA) && (*
this <= keyB));
609 return ((*
this >= keyA) || (*
this <= keyB));
629 for (uint32_t i=0; i<aSize; i++) {
658 sha1.
Update((uint8_t*)(&(*input.begin())), input.size());
661 mpn_set_str(newKey.
key, (
const uint8_t*)temp,
662 (
int)std::min((uint32_t)(aSize *
sizeof(mp_limb_t)), 20U), 256);
672 if (exponent >= keyLength) {
673 throw cRuntimeError(
"OverlayKey::pow2(): "
674 "exponent >= keyLength!");
679 newKey.
key[exponent/GMP_LIMB_BITS] =
680 (mp_limb_t)1 << (exponent % GMP_LIMB_BITS);
689 cout << endl <<
"--- Add test ..." << endl;
691 cout <<
" key=" << key << endl;
692 cout <<
" key += 987654321 = " << (key+=987654321) << endl;
693 cout <<
" prefix++ : " << (++key) << endl;
694 cout <<
" postfix++ : " << (key++) << endl;
695 cout <<
" key=" << key << endl;
700 cout << endl <<
"--- Compare test ..." << endl;
701 cout <<
" 256 < 10 = "<< (k1 < k2) <<
" k1="<<k1<<endl;
702 cout <<
" 256 > 10 = "<< (k1 > k2) <<
" k2="<<k2<<endl;
704 cout <<
" 10 isBetween(3, 256)=" << k2.
isBetween(k3, k1) << endl;
705 cout <<
" 3 isBetween(10, 256)=" << k3.isBetween(k2, k1) << endl;
706 cout <<
" 256 isBetween(10, 256)=" << k1.
isBetween(k2, k1) << endl;
707 cout <<
" 256 isBetweenR(10, 256)=" << k1.
isBetweenR(k2, k1) << endl;
728 cout << endl <<
"--- Warp around test ..." << endl;
731 cout <<
"k1=max= " << k1.
toString(16) << endl;
732 cout <<
"k1+1 = " << (k1 + 1).toString(16) << endl;
733 cout <<
"k1+2 = " << (k1 + 2).toString(16) << endl;
736 cout <<
"k1=0= " << k1.
toString(16) << endl;
737 cout <<
"k1-1 = " << (k1 - 1).toString(16) << endl;
738 cout <<
"k1-2 = " << (k1 - 2).toString(16) << endl;
744 cout << endl <<
"--- Distance test ..." << endl;
746 cout <<
"KeyRingMetric::distance(1, max)="
748 cout <<
"KeyCwRingMetric::distance(1, max)="
750 cout <<
"KeyRingMetric::distance(max, 1)="
752 cout <<
"KeyCwRingMetric::distance(max, 1)="
756 cout << endl <<
"--- RandomSuffix and log2 test ..." << endl;
758 for (uint32_t i=0; i<k1.
getLength(); i++) {
760 cout <<
" " << k2.
toString(16) <<
" log2=" << k2.log_2() << endl;
762 cout << endl <<
"--- RandomPrefix and log2 test ..." << endl;
764 for (uint32_t i=0; i<k1.
getLength(); i++) {
766 cout <<
" " << k2.
toString(16) <<
" log2=" << k2.log_2() << endl;
769 cout << endl <<
"--- pow2 test..." << endl;
770 for (uint32_t i=0; i<k1.
getLength(); i++) {
772 cout <<
" 2^" << i <<
" = " << k2.toString(16) <<
" log2="
773 << k2.log_2() << endl;
776 cout << endl <<
"--- Bits test ..." << endl <<
" ";
777 const char* BITS[] = {
"000",
"001",
"010",
"011",
"100",
"101",
"110",
"111" };
781 cout <<
" = " << endl <<
" ";
786 cout << endl <<
"--- SHA1 test ... (verified with test vectors)" << endl;
788 <<
" = da39a3ee5e6b4b0d3255bfef95601890afd80709" << endl;
789 cout <<
" 'Hello World' string: "
791 <<
" = 0a4d55a8d778e5022fab701977c5d840bbc486d0" << endl;
801 key[aSize-1] &= GMP_MSB_MASK;
809 opp_error(
"OverlayKey::compareTo(): key is unspecified!");
810 return mpn_cmp(key,compKey.
key,aSize);
816 memset( key, 0, aSize *
sizeof(mp_limb_t) );
824 uint32_t* chunkPtr = (uint32_t*)r1p;
826 for (uint32_t i=0; i < ((r1n*
sizeof(mp_limb_t) + 3) / 4); i++) {
827 chunkPtr[i] = intuniform(0, 0xFFFFFFFF);
831 #ifdef __GMP_SHORT_LIMB
832 #define GMP_TYPE unsigned int
834 #ifdef _LONG_LONG_LIMB
835 #define GMP_TYPE unsigned long long int
837 #define GMP_TYPE unsigned long int
847 doPacking(b,(uint32_t*)this->key, MAX_KEYLENGTH / (8*
sizeof(uint32_t)) +
848 (MAX_KEYLENGTH % (8*
sizeof(uint32_t))!=0 ? 1 : 0));
856 doUnpacking(b,(uint32_t*)this->key, MAX_KEYLENGTH / (8*
sizeof(uint32_t)) +
857 (MAX_KEYLENGTH % (8*
sizeof(uint32_t))!=0 ? 1 : 0));