Bitcoin Forum
May 17, 2024, 06:24:00 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [35] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 ... 142 »
  Print  
Author Topic: Pollard's kangaroo ECDLP solver  (Read 55972 times)
WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1064
Merit: 219

Shooters Shoot...


View Profile
June 02, 2020, 09:33:30 PM
 #681

I am working on pool to solve keys together.
It is shema how it should be:


HelpServer and HelpClient needed to map each DP to a specific account.
As you can see in the next picture each sent DP is added to a specific account.



So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.



Buddy, you realy thant crack 1 Btc pusle ? I have many BTC REAL PUBKEYS with 40 BTC AND MORE fore cooperate crack. Do you agree crack 40 BTC and more and share profit ? 40 BTC - this is a forgotten for 10 years and wallet. If not, your 1 BTC puzle not interested for for cooperation crack. If you ready crack more then 1 BTC, we well can ccoperate and get some profit, and share profit with Jean_Luc. If you not Bro, I will do it yourself. My country is a sheet country and I Thant go away from sheet.

Huh?

Send me what info you have on your forgotten wallets.

Hello. I was talk with the Etar, and not talk bout forgotten wallets, but only forgotten  addressee. Ditherent is understand for you ? If you realy can crck forgotten adress You Are welcome to pm me.
Says you do not accept PMs from "Newbies"
arulbero
Legendary
*
Offline Offline

Activity: 1915
Merit: 2074


View Profile
June 02, 2020, 09:54:05 PM
 #682

I am working on pool to solve keys together.
-----
So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.

Are you sure?

key #110 was solved with 2^30.55 DP in 2 days

A normal cpu can compute consecutive keys very fast, my cpu computes almost 30 Mkeys/s, let's say 2^24 keys/s; it would take less than 2 minutes to check 2^30 points

computing random points is slower, but even if it takes x100, we are talking about 3 hours for the entire hash table.

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.

If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?
BitCrack
Jr. Member
*
Offline Offline

Activity: 30
Merit: 122


View Profile
June 02, 2020, 11:13:27 PM
Merited by Tamarindei (1)
 #683

I am working on pool to solve keys together.
-----
So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.

Are you sure?

key #110 was solved with 2^30.55 DP in 2 days

A normal cpu can compute consecutive keys very fast, my cpu computes almost 30 Mkeys/s, let's say 2^24 keys/s; it would take less than 2 minutes to check 2^30 points

computing random points is slower, but even if it takes x100, we are talking about 3 hours for the entire hash table.

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.

If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?

You would need to check that the DP is actually valid though. That involves performing the entire walk. If you did this for every DP you would be re-doing the entire computation.



One way to do this would to include a checksum with the DP whete the checksum is the count of each jump point that makes up the DP. To verify it the server multiplies and adds the counts and the jump points together. This would involve more work for the client since it would need to keep count for every walk.
WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1064
Merit: 219

Shooters Shoot...


View Profile
June 02, 2020, 11:17:15 PM
 #684

I am working on pool to solve keys together.
-----
So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.

Are you sure?

key #110 was solved with 2^30.55 DP in 2 days

A normal cpu can compute consecutive keys very fast, my cpu computes almost 30 Mkeys/s, let's say 2^24 keys/s; it would take less than 2 minutes to check 2^30 points

computing random points is slower, but even if it takes x100, we are talking about 3 hours for the entire hash table.

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.

If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?

You would need to check that the DP is actually valid though. That involves performing the entire walk. If you did this for every DP you would be re-doing the entire computation.



One way to do this would to include a checksum with the DP whete the checksum is the count of each jump point that makes up the DP. To verify it the server multiplies and adds the counts and the jump points together. This would involve more work for the client since it would need to keep count for every walk.
Could you split the work; have separate server/another CPU verifying the DPs, once it checks, it dumps the files; if invalid DP is found, it notifies main server?
COBRAS
Member
**
Offline Offline

Activity: 854
Merit: 22

$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk


View Profile
June 02, 2020, 11:32:51 PM
 #685

I am working on pool to solve keys together.
It is shema how it should be:


HelpServer and HelpClient needed to map each DP to a specific account.
As you can see in the next picture each sent DP is added to a specific account.



So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.



Buddy, you realy thant crack 1 Btc pusle ? I have many BTC REAL PUBKEYS with 40 BTC AND MORE fore cooperate crack. Do you agree crack 40 BTC and more and share profit ? 40 BTC - this is a forgotten for 10 years and wallet. If not, your 1 BTC puzle not interested for for cooperation crack. If you ready crack more then 1 BTC, we well can ccoperate and get some profit, and share profit with Jean_Luc. If you not Bro, I will do it yourself. My country is a sheet country and I Thant go away from sheet.

Huh?

Send me what info you have on your forgotten wallets.

Hello. I was talk with the Etar, and not talk bout forgotten wallets, but only forgotten  addressee. Ditherent is understand for you ? If you realy can crck forgotten adress You Are welcome to pm me.
Says you do not accept PMs from "Newbies"

Now I was accept. Your's messages are welcomed !!!

$$$ P2P NETWORK FOR BTC WALLET.DAT BRUTE F ORCE .JOIN NOW=GET MANY COINS NOW !!!
https://github.com/phrutis/LostWallet  https://t.me/+2niP9bQ8uu43MDg6
Tamarindei
Newbie
*
Offline Offline

Activity: 17
Merit: 25


View Profile
June 03, 2020, 12:14:16 AM
Last edit: June 03, 2020, 12:29:26 AM by Tamarindei
 #686

I am working on pool to solve keys together.
-----
So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.

Are you sure?

key #110 was solved with 2^30.55 DP in 2 days

A normal cpu can compute consecutive keys very fast, my cpu computes almost 30 Mkeys/s, let's say 2^24 keys/s; it would take less than 2 minutes to check 2^30 points

computing random points is slower, but even if it takes x100, we are talking about 3 hours for the entire hash table.

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.

If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?

You would need to check that the DP is actually valid though. That involves performing the entire walk. If you did this for every DP you would be re-doing the entire computation.



One way to do this would to include a checksum with the DP whete the checksum is the count of each jump point that makes up the DP. To verify it the server multiplies and adds the counts and the jump points together. This would involve more work for the client since it would need to keep count for every walk.

Is it really that important a DP was generated by a walk? Why aren't any points that satisfy the DP criteria (bitmask) valid and usefull?
Edit: I understand now that each DP must be generated by a real Pollard Kangaroo walk for the synchronizing effect of the walk.

Maybe different approach for parallelizing the work:

Q = our target pubkey in 115 bit range

If you have 16 GPUs prepare a new set S of pubkeys:

for n = 0 to 16
  S[n] = (Q-n)/16

Now you have a set S with 16 new derived pubkeys where only one is in the range targetBitrange-4 (for 115 it is now in 111 bit range).
So it is true that 15 GPUs will work on pubkeys that are in a different range and this work is useless. But one GPU is working in the correct 111 bit range.

Would this be a benefit?

Edit:
BitCrack, I like your solution for verifying the work but maybe it can be faked too when there is a bad actor that wants to mess with the pool data?

WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1064
Merit: 219

Shooters Shoot...


View Profile
June 03, 2020, 01:30:10 AM
 #687

I am working on pool to solve keys together.
-----
So far, the biggest problem is the verification of DP. The CPU is not able to check every DP, it simply does not have enough resources for this.
As an option, in order to prevent forged DPs, HelpServer can check a few percent of the sent.
And send to the ban if the client sends the wrong points.
Maybe someone knows how to easily and effectively check points, because multiplying the distance by G is a resource-intensive process.

Are you sure?

key #110 was solved with 2^30.55 DP in 2 days

A normal cpu can compute consecutive keys very fast, my cpu computes almost 30 Mkeys/s, let's say 2^24 keys/s; it would take less than 2 minutes to check 2^30 points

computing random points is slower, but even if it takes x100, we are talking about 3 hours for the entire hash table.

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.

If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?
What part of code needs tweaked to work with smaller priv keys?
MrFreeDragon
Sr. Member
****
Offline Offline

Activity: 443
Merit: 350


View Profile
June 03, 2020, 02:02:14 AM
 #688

-snip-
You would need to check that the DP is actually valid though. That involves performing the entire walk. If you did this for every DP you would be re-doing the entire computation.

One way to do this would to include a checksum with the DP whete the checksum is the count of each jump point that makes up the DP. To verify it the server multiplies and adds the counts and the jump points together. This would involve more work for the client since it would need to keep count for every walk.

Checking the DPs only for validity does not mean performing the entire work again. Kangaroos are jumping from one point to another based on visited x-coordinate, and as soon as kangaroo lands the x-coordinate with the determined pattern (i.e. coordinate with 25 leading zeros from total 256 bits for DP 25) this coordinate is saved to hashtable together with the distance. So we have saved distance and x-coordinate (only 2nd half of it with length 128 bit).

To check one tame point from hashtable we just need perform one elliptic curve multiplication - converting distance (i.e. private key) to public key and compare last 128 bits of x-coordinate with saved in hashtable. For wild points we should perform one elliptic curve multiplication and addition/subtraction - compute public key from the distance and add/subtract the received point with the target public key, and compare the resulted x-coordinate with hashtable. {ok, actually it is not one addition and multiplication it consists from 32 additions, but it depends on the used algorithm and pre-computed points}

Also no need to save the whole path of the kangaroos. Only the final distinguished point (DP) with the total distance is important.

But we should not make the whole job again to check the DP. Client should perform approximately 2^25 jumps (operations) in order to find one DP. On server side we need to perform just one operation.

Agree with arulbero

Interested2020
Newbie
*
Offline Offline

Activity: 3
Merit: 0


View Profile
June 03, 2020, 02:03:26 AM
 #689

Hello,

Thank you for allowing public testing of your code.

I am using CUDA 10.2 and VS 2017 (15.9), Windows Server 2019 on Google Console with a GPU Tesla V100.

I am trying to compile in VS but I can't seem to get rid of this error:

Code:
error : Designtime build failed for project 'C:\Users\danh\Desktop\kg\Kangaroo-master\VC_CUDA102\Kangaroo.vcxproj' configuration 'Release|x64'. IntelliSense might be unavailable.
Set environment variable TRACEDESIGNTIME = true and restart Visual Studio to investigate.

Any suggestions appreciated.

Thanks for your time.

Dan


Tamarindei
Newbie
*
Offline Offline

Activity: 17
Merit: 25


View Profile
June 03, 2020, 02:23:28 AM
 #690

-snip-
Checking the DPs only for validity does not mean performing the entire work again. Kangaroos are jumping from one point to another based on visited x-coordinate, and as soon as kangaroo lands the x-coordinate with the determined pattern (i.e. coordinate with 25 leading zeros -----snip-

As far as I understand it is important that the DP is from a real kangaroo walk.

The difference:
As soon as a kangaroo hits a point (a point that is not qualified to be a DP by bitmask) that has been visited by a kangaroo of the other type, their walks are synchronized and the next DP they find will definately result in a collision and PK is found.
This is not the case with randomly selected points in the range that fullfill the DP bitmask criteria.


It is possible that there will be a collision with these kind of "not real walk" points though.



Tamarindei
Newbie
*
Offline Offline

Activity: 17
Merit: 25


View Profile
June 03, 2020, 02:30:35 AM
 #691

-snip-
Code:
error : Designtime build failed for project 'C:\Users\danh\Desktop\kg\Kangaroo-master\VC_CUDA102\Kangaroo.vcxproj' configuration 'Release|x64'. IntelliSense might be unavailable.
Set environment variable TRACEDESIGNTIME = true and restart Visual Studio to investigate.

-snip-

Hi Dan.
I am not using Visual Studio.
I googled the problem and found some solutions that say you should repair the project (I think there is a menu option) or upgrade your visual studio.
Etar
Sr. Member
****
Offline Offline

Activity: 616
Merit: 312


View Profile
June 03, 2020, 04:41:55 AM
Last edit: June 03, 2020, 04:54:41 AM by Etar
 #692

-snip-
If you need it I can put together a C program, I think at least 100k key/s are possible, then 2^30 points in less than 3 hours; what speed do you think you need? How much DPs you want to check per hour?
At picture 1 2080ti produce 2200DPs every 2seconds. the same 2^30.5(Nop) / 20^20(Dpsize)=2^10.5 DP/s = 1176
If there will be for example 100 GPU 2080ti it is 110K DP/s need to be verified.
To prevent crash kangaroo server we need only check hash mask. But it is not enouch to prevent addiding job to bad actor.
Everyone can easy make forge DP where mask correct(0<=mask<1<<18), but distance and x-coordinate is fake.
Without verification this DP, actor will get +1DP to his account.
The same like in mining where each share from miner verified we need verify each DP.
Jean_Luc (OP)
Sr. Member
****
Offline Offline

Activity: 462
Merit: 696


View Profile
June 03, 2020, 04:58:43 AM
 #693

As said in the README the server is simple and doesn't have an authentication mechanism.
It is quite easy for a hacker to make it crash or make it generate wrong collision to make the server unusable.
So, do not export this server to the world or hide the ip and port and give server address to trusted person only.
Tamarindei
Newbie
*
Offline Offline

Activity: 17
Merit: 25


View Profile
June 03, 2020, 07:08:57 AM
 #694

In the end Jean Luc took the chance from all with the knowledge of creating a working Pollard Kangaroo for GPU and gave it to those with the power but no knowledge.
I am sure #115, #120 and #125 will go to zielar and no pool can compete. gg.
Jean_Luc (OP)
Sr. Member
****
Offline Offline

Activity: 462
Merit: 696


View Profile
June 03, 2020, 07:18:52 AM
Last edit: June 03, 2020, 07:34:34 AM by Jean_Luc
 #695

I am sure #115, #120 and #125 will go to zielar and no pool can compete. gg.

I disagree.
I spent much time to explain in the readme, in this topics or in the code the way to choose best parameters and trap to avoid.
Zielar has also to win his life and cannot spend full time to solve these puzzles.
It is far from sure that Zielar will win all the races.

Anyway, I'm working on the 1.9 in order to integrate mods from PatataFritas and support of -ws for clients.


Edit: You have no idea who Zielar is actually. He is a very competent person in his domain, I must say that from time to time I pain to follow him !

arulbero
Legendary
*
Offline Offline

Activity: 1915
Merit: 2074


View Profile
June 03, 2020, 07:25:20 AM
Last edit: June 03, 2020, 07:50:01 AM by arulbero
 #696

You would need to check that the DP is actually valid though. That involves performing the entire walk. If you did this for every DP you would be re-doing the entire computation.

As far as I understand it is important that the DP is from a real kangaroo walk.

The difference:
As soon as a kangaroo hits a point (a point that is not qualified to be a DP by bitmask) that has been visited by a kangaroo of the other type, their walks are synchronized and the next DP they find will definately result in a collision and PK is found.
This is not the case with randomly selected points in the range that fullfill the DP bitmask criteria.

It is possible that there will be a collision with these kind of "not real walk" points though.

I agree with you, but I remember you that a proof of work is always a probabilistic task, we cannot redo the entire work to be sure that the entire work is correct.

My proposal:

let's say DP=25, we perform a check on 2 levels, a result and a process check:

level 1) result check

we check that each DP fulfils:
                   - has at least 25 zeros bits
                   - its private key is correct and lies in the correct interval

level 2) process check, proof that the points were generated with a correct path

- we check that there are at least 1/2000 of the points with x-coordinate with at least 25 + 10 zeros
- we redo only the complete path of each kangaroo that ends with a DP with at least 35 zeros

The second check is a valid proof of work, because to generate (in the correct way, with the correct jumps) a single DP with 35 zeros you need to generate correctly on average 2^10 = 1024 kangaroos with a end point with 25 zeroes, you can't fake it.

Obviously you can choose to modify + 10 zeros in +12 or +8, as you prefer.
In this way you need to redo only a small fraction on the entire work, but it is a very significative fraction, not a simple random sample.

There are no shortcuts to generate this correct fraction (DP = 35) of the entire work without doing the entire work, but the checker needs only to do a check on the fraction.
arulbero
Legendary
*
Offline Offline

Activity: 1915
Merit: 2074


View Profile
June 03, 2020, 07:59:40 AM
Last edit: June 03, 2020, 08:13:49 AM by arulbero
 #697

With a simple python script I can get 2^12 keys/s, but it is not tailored for the public keys with private keys so short (under 128 bit) it could reach at least 2^13 keys/s with keys so short.
What part of code needs tweaked to work with smaller priv keys?


Here there is the explanation on how it works my script:
https://bitcointalk.org/index.php?topic=5202064.msg54213558#msg54213558

Basically you have to split the private key as a sum of precomputed private keys.

In these sentences:
Quote
I use 64 groups of 15 points = 960 precomputed points
...
I split a 256 bit key in 64 pieces of 4 bit and I compute 63 additions.


you can half the groups (32 pieces of 4 bit instead of 64 for a total of 480 precomputed points) and the additions needed (31 instead of 63) if you use 128bit-private keys.

You can have a estimation too on how long it takes to perform k*G against P+Q,  about 31 times (or 63 times) more than a simple addition P+Q (that we use in the kangaroo algorithm).

I refer only to the cpu speed, because on gpus things are different, we can't exploit a fast access on a huge memory for the precomputed points.
Tamarindei
Newbie
*
Offline Offline

Activity: 17
Merit: 25


View Profile
June 03, 2020, 08:29:54 AM
 #698

I am sure #115, #120 and #125 will go to zielar and no pool can compete. gg.

I disagree.
I spent much time to explain in the readme, in this topics or in the code the way to choose best parameters and trap to avoid.
Zielar has also to win his life and cannot spend full time to solve these puzzles.
It is far from sure that Zielar will win all the races.

Anyway, I'm working on the 1.9 in order to integrate mods from PatataFritas and support of -ws for clients.


Edit: You have no idea who Zielar is actually. He is a very competent person in his domain, I must say that from time to time I pain to follow him !



Sorry Jean Luc. I wrote a little offending. I put some resources into the search for #110 so I was little emotional for a moment. I apologize.
Jean_Luc (OP)
Sr. Member
****
Offline Offline

Activity: 462
Merit: 696


View Profile
June 03, 2020, 08:38:42 AM
 #699

The ComputePublicKey() in kangaroo use 32 blocks of 256 precomputed points and zero are checked so it performs:
31 adds max for a full privkey (nothing when a zero byte is present) and a modular inversion.
There is also a ComputePublicKeys() which group modular inversions.
arulbero
Legendary
*
Offline Offline

Activity: 1915
Merit: 2074


View Profile
June 03, 2020, 08:50:43 AM
Last edit: June 03, 2020, 09:09:38 AM by arulbero
 #700

The ComputePublicKey() in kangaroo use 32 blocks of 256 precomputed points and zero are checked so it performs:
31 adds max for a full privkey (nothing when a zero byte is present) and a modular inversion.
There is also a ComputePublicKeys() which group modular inversions.


That means you need only 16 blocks of 255 (why 256?) precomputed points for a 128-bit privkey, only 15 adds, not too much respect to a single addition.

Split a 128-bit in 16 pieces (each piece has 128/16=8 bit -> 255 elements) and  compute only 16-1 = 15 group additions for each key.

Just for example, if you have a 128 bit key:

key = 10101010 10100000 11111111 01000010 ...  11101010

split in 16 pieces of 128/16=8 bits:

(10101010)*2^120 + (10100000)*2^112 + (11111111)*2^104 + (01000010)*2^96 + .... + (11101010)2^0
Code:
00000001   00000010   00000011   ...    11111111      --> 255 possibilities

  2^0        2*2^0     3*2^0     ...     255*2^0      --> one of these is (11101010)*2^0

  ...         ...      ...       ...       ...

2^(12*8)  2*2^(12*8)  3*2^(12*8) ...  255*2^(12*8)    --> one of these is (01000010)*2^96

2^(13*8)  2*2^(13*8)  3*2^(13*8) ...  255*2^(13*8)    --> one of these is (11111111)*2^104

2^(14*8)  2*2^(14*8)  3*2^(14*8) ...  255*2^(14*8)    -->  one of these is (10100000)*2^112
 
2^(15*8)  2*2^(15*8)  3*2^(15*8) ...  255*2^(15*8)    -->  one of these is (10101010)*2^120
Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [35] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 ... 142 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!