Pages:
Author

Topic: Bamboo: New crypto using ED25519 signing keys - page 7. (Read 4650 times)

member
Activity: 61
Merit: 17
Okay I absolutely see the problem perfectly now!  Shocked
newbie
Activity: 18
Merit: 0
Thank you, the questions only arised because of the messed assignment "newA = stripe" (seems like 32 times overwritten using operator SHA256Hash::operator=( uint8_t) ). A moderator merged with my second post where I had already figured out. There I say
This is a bad hash function because a good hash function should have uncorrelated and approximate random outputs. The above function will return complete 0 vectors with higher probability than other outputs because in case that initially val==0 (which is roughly in about 1/10^10 of the cases) in all iterations delta==0 and nextIdx==0 and val==0 such that stripe==0 and newA== NULL_SHA256_HASH (which satisfies even the most difficult target) is returned (which is 1/(2^256) of all possible outputs). Therefore this output occurs disproportionately more often, orders of magnitudes more often. Something similar happens for val equal to multiples of the divisors in the modulo operations because then still delta==0 and nextId==0 such that newA will have one byte repeated, i.e. for val equal to multiples of the least common multiple of  32-4 and NUM_SHA_DIGESTS, which is 7000. This means at least every 7000th input will yield an output with one byte repeated.
I would not roll out my own hash function. It can easily happen that your hash function does not scatter well in its return values such that some targets might become unmineable which will kill your blockchain. (Do you really known that it is possible that a certain number of leading zeros can be achieved as an output?). In your case it is the opposite: every 10^10 hashes you can easily have one that has complete zeros, i.e. will certainly mine the block at every difficulty.

[moderator's note: consecutive posts merged]
and this still holds true. What I'm saying is that for example every 2^32 tries the value
uint32_t val = *(uint32_t*)digests[0].data();
will be uint32_t(0) and in this case the function will return NULL_SHA256_HASH, i.e. this output will be overrepresented because NULL_SHA256_HASH should only occur every 2^256 hashes. Not only overrepresented but also will break difficulty adjustment. If blocks are mined too quickly, the difficulty adjustment cannot do something against it because if NULL_SHA256_HASH is returned it will always mine a new block even the with strictest difficulty requirement. Furthermore multiple blocks in the chain could have the same hash NULL_SHA256_HASH.

And why are you not using a RAII lock such as unique_lock or lock_guard here https://github.com/mr-pandabear/panda-coin/commit/0dd7b6a6ac266ec597da522198d395ee3d7b492a#diff-bef89388d9552fd0e9f163ac736709c197fe7888c036658069689d33f5275020R267
member
Activity: 61
Merit: 17
Windows binaries are available on the github project page (https://github.com/mr-pandabear/panda-coin/)

Direct link: https://github.com/mr-pandabear/panda-coin/releases/download/v0.2-alpha/panda-coin-win-20211221.zip


@danglingnullptr ... so here is explanation of the questions you posit:

{EDIT: so the issue is that the forum messes up the array code ... the code posted in the forum has the array brackets removed it should be newA [ i ] }

I link the code in a github gist here: https://gist.github.com/mr-pandabear/2a97a1f008145d81ccb3982c71248c93


1. Why you are overwriting newA in every loop iteration?
newA is of type std::array ... so the outer loop fills in each "stripe" of the hash, while the inner loop computes the value of the stripe. This is why it is "newA [ i ] = stripe"

2. Why does this loop have 32 rounds?
To fill in each of the 32 bytes of the output SHA256 Hash

3. Where did you define SHA256Hash& SHA256Hash::operator=( uint8_t) ? Maybe I will see it when I look at the rest of your project, but for now this means that your final hash can only have 256 different values because this is true for the variable stripe.
(See above)


The idea here is that we use the values of the vector of SHA digests to generate the value of each stripe. These SHA digests *must* be stored in memory because they are randomly accessed based on the previous value. val and nextIdx create a random pointer into the hash and the nextIdx is a function of the previously read value within the SHA hash.

You can think of the value of newA[ i ] to be a sum of a random walk over the 8 byte portions within the (large) vector of SHA256Hashes we generate.


Great catches re: Timestamp medians (didn't know that was how Bitcoin does it!)... as well as the C style casts. They are used in a few places and will need to be re-written to be portable.
newbie
Activity: 18
Merit: 0
I have seen on Github that there was a hack of malicious miners that manipulate timestamps. The fix is a bit fragile because
1. https://github.com/mr-pandabear/panda-coin/blob/44875696e210e1359d109d7a08cc795209b6b2fb/src/server/blockchain.cpp#L303 depends on the server timestamp they can be out of sync especially it the project goes decentralized one day. Bitcoin uses a 2 hour tolerance I think.
2. And it uses a median rule, see https://en.bitcoin.it/wiki/Block_timestamp instead of your hard rule of strictly increasing timestamps https://github.com/mr-pandabear/panda-coin/blob/44875696e210e1359d109d7a08cc795209b6b2fb/src/server/blockchain.cpp#L301
Maybe adopt these things?
Furthermore, I spotted another bug of undefined behaviour: You cannot do C-style casts or reinterpret_casts at arbitrary addresses because of memory alignment https://stackoverflow.com/a/32590117. For example processors cannot access aligned 4 byte integer types at addresses not equal to a multiple of 4, so casting as done in
https://github.com/mr-pandabear/panda-coin/blob/44875696e210e1359d109d7a08cc795209b6b2fb/src/tools/server.cpp#L166
or https://github.com/mr-pandabear/panda-coin/blob/44875696e210e1359d109d7a08cc795209b6b2fb/src/tools/server.cpp#L184
is undefined behaviour. Such castings appear at more places in the code base.

And I was not the attacker exploiting the mining timestamp bug. I am not even mining this coin as it is not decentralized at this stage. Amazon AWS where the central servers are located (and thus the NSA) track all miners' IPs if they are not using a proxy. But it is instructive to see this project grow and I like the clean code of mrpandabaer Smiley

Furthermore
Hi, Where can i find the miner binaries for windows ??

thnx in advance !



Don't recommend supporting such projects, the linux release was released and windows mining was not available for a long while. Pathetic for launch for a blockchain.
I think every project starts only one platform in its early stage (for Bitcoin it was Windows). That's normal, not pathetic. In return for the user inconvenience you get more coins at this stage because there is less competition.
member
Activity: 289
Merit: 18
Hi, Where can i find the miner binaries for windows ??

thnx in advance !

Don't recommend supporting such projects, the linux release was released and windows mining was not available for a long while. Pathetic for launch for a blockchain.
newbie
Activity: 3
Merit: 0
Hi, Where can i find the miner binaries for windows ??

thnx in advance !
newbie
Activity: 18
Merit: 0
Will look at the code in more detail tomorrow but for now I do not understand :
1. Why you are overwriting newA in every loop iteration?
2. Why does this loop have 32 rounds?
3. Where did you define SHA256Hash& SHA256Hash::operator=( uint8_t) ? Maybe I will see it when I look at the rest of your project, but for now this means that your final hash can only have 256 different values because this is true for the variable stripe.
Some comments:
a) Please do not i for both the outer and the inner loop (even though i is not accessed),
b) Some people say preincrement is faster than postincrement, so use ++i.



I think you meant newA[i|=stripe so I am considering this(Note: Now I see that brackets are not printed in this forum because this notation is used for links so I do this [i|, i.e. closing with |):
-------
#define NUM_SHA_DIGESTS 1000
SHA256Hash memoryHardHash(SHA256Hash &a) {
    vector digests;
    SHA256Hash last = a;
    // Build vector of SHA hashes
    for(int i = 0; i < NUM_SHA_DIGESTS; i++) {
        SHA256Hash h = SHA256((const char*)last.data(), 32);
        digests.push_back(h);
        last = h;
    }
   
    SHA256Hash newA = NULL_SHA256_HASH;

    uint32_t val = *(uint32_t*)digests[0].data();
    uint32_t nextIdx = val % NUM_SHA_DIGESTS;
    for (int i = 0; i < 32; ++i) {
        uint8_t stripe = 0;
        for(int j = 0; j < NUM_SHA_DIGESTS; ++j) {
            uint8_t delta = val % (32 - sizeof(uint32_t));
            val = *(uint32_t*)(digests[nextIdx].data() + delta);
            nextIdx = val % NUM_SHA_DIGESTS;
            stripe += *((uint8_t*)&val);
        }
        newA[i| = stripe;
    }

    return newA;
}
------

This is a bad hash function because a good hash function should have uncorrelated and approximate random outputs. The above function will return complete 0 vectors with higher probability than other outputs because in case that initially val==0 (which is roughly in about 1/10^10 of the cases) in all iterations delta==0 and nextIdx==0 and val==0 such that stripe==0 and newA== NULL_SHA256_HASH (which satisfies even the most difficult target) is returned (which is 1/(2^256) of all possible outputs). Therefore this output occurs disproportionately more often, orders of magnitudes more often. Something similar happens for val equal to multiples of the divisors in the modulo operations because then still delta==0 and nextId==0 such that newA will have one byte repeated, i.e. for val equal to multiples of the least common multiple of  32-4 and NUM_SHA_DIGESTS, which is 7000. This means at least every 7000th input will yield an output with one byte repeated.
I would not roll out my own hash function. It can easily happen that your hash function does not scatter well in its return values such that some targets might become unmineable which will kill your blockchain. (Do you really known that it is possible that a certain number of leading zeros can be achieved as an output?). In your case it is the opposite: every 10^10 hashes you can easily have one that has complete zeros, i.e. will certainly mine the block at every difficulty.

[moderator's note: consecutive posts merged]
member
Activity: 61
Merit: 17
The block mint time is only 30 seconds, there is enough hash rate in the network that it is unlikely to get a block unless you run the miner for a while. I would try overnight and see if you get something. What are your specs?
member
Activity: 61
Merit: 17
I have other higher priority items but had an itch to pontificate... I sat down and hacked for a bit and came up with something I think should be memory-hard (ASIC resistant) and cross-platform compatible. It's inspired by the basic thesis of scrypt: build a large vector of expensive to compute random numbers and access them in a random fashion to generate the final hash. We would simply wrap our POW answer with memoryHardHash when validating our POW. I re-purpose SHA256 as an RNG here.

Would love someone to take a look at this (@danglingnullptr are you still here?!)
-----

#define NUM_SHA_DIGESTS 1000

SHA256Hash memoryHardHash(SHA256Hash &a) {
    vector digests;
    SHA256Hash last = a;
    // Build vector of SHA hashes
    for(int i = 0; i < NUM_SHA_DIGESTS; i++) {
        SHA256Hash h = SHA256((const char*)last.data(), 32);
        digests.push_back(h);
        last = h;
    }
    
    SHA256Hash newA = NULL_SHA256_HASH;

    uint32_t val = *(uint32_t*)digests[0].data();
    uint32_t nextIdx = val % NUM_SHA_DIGESTS;
    for (int i = 0; i < 32; i++) {
        uint8_t stripe = 0;
        for(int i = 0; i < NUM_SHA_DIGESTS; i++) {
            uint8_t delta = val % (32 - sizeof(uint32_t));
            val = *(uint32_t*)(digests[nextIdx].data() + delta);
            nextIdx = val % NUM_SHA_DIGESTS;
            stripe += *((uint8_t*)&val);
        }
        newA = stripe;
    }

    return newA;
}

-----
Of course we will want to make some perf tweaks (e.g pre-allocating the 256MB vector rather than pushing on to it... but the basic algorithm should be pretty clear).


I'm not confident it works, but if it does ... we will have a huge win for ASIC + GPU resistance Cheesy + I will have invented a new POW algorithm =)
full member
Activity: 312
Merit: 102
Happy to host some nodes to help with start-up. As per other requests, a Discord server would be very helpful for speedy communication. Also agree with you considering making it harder for ASIC/GPU miners Smiley
member
Activity: 61
Merit: 17
I'm not 100% on the 10k block change. The main issue I'm solving for is that we don't want really small block times as a result of miner manipulation. Small block times causes tons of forks in the chain and lowers the overall usability of the network (though it benefits miners as they need to extend fewer resources to mine coins). At the early stage, if we have very few miners, a miner can pull out for a while, wait for difficulty to drop, then start mining again. If it takes 1 week to do this the incentive for this manipulation is much lower.


In addition to the short term roadmap, here are two longer term roadmap items that I'm contemplating and would appreciate feedback on:

1) Digital asset support. This would enable the creation of "digital assets" which can be listed as for sale and transferred amongst participants. The implementation of this functionality is actually fairly simple. You can create a SHA256 hash that you "own" in exchange for a minting fee paid to miners. This asset can then be listed "for sale" at a specified price. Anyone can initiate a transfer of funds to you in exchange for switching them to be the owner. Everything in PandaCoin is an account based model like ETH, (rather than UTXO like bitcoin) -- which actually makes this pretty straightforward to implement.

2) More ASIC/GPU resistant algorithms: There are a lot, e.g GhostRider, Scrypt, X16R that would be fairly simple to integrate. Part of me wants to do something totally new here, in particular, adding an additional NP-Complete challenge check. See:

- https://pphili.github.io/2017/09/01/blockchain.html
- https://pure.royalholloway.ac.uk/portal/files/39587484/Accepted_Manuscript.pdf
 
Beyond these two, I don't want to add too many features. The goal has always been to have a simple store of value currency with fast transactions and not too many bells and whistles.
newbie
Activity: 21
Merit: 1

Great job and good news!)

-- Switching difficulty calc from once every 100 blocks to every 10,000 blocks (weekly)

But are you sure this is a good idea?
member
Activity: 61
Merit: 17
Here is the current proposal for block halving:
https://imgur.com/BjOSufc

First 1M reward = 50BMB
Next 1M reward = 25BMB
Next 2M reward = 12.5BMB

Gives a total circulation of 100M BMB. I will be pushing a very major update to main net in the coming weeks and will release the nodes into the wild...so anyone and their mother should be able to run a node now. This is how the network grows up.

Unfortunately we have made optimizations that require us to restart the chain. We will, of course, maintain wallets that have been mined in the new genesis when this happens so miner totals will remain unaffected. I encourage you guys to continue mining and stress testing the infra. So far we have been getting less and less downtime.

I regret having to re-fork, but there just wasn't any other way possible to do proper block-halving as well as the other updates we needed in an elegant fashion.

Changes we are implementing:
-- Removal of transaction nonces and blockID storage within transactions -- this saves 12 bytes per transaction
-- Block Halving as described above
-- Improved difficulty calculations
-- Switching block mint time from 30 sec -> 1 min
-- Switching difficulty calc from once every 100 blocks to every 10,000 blocks (weekly)
-- Increasing max TX per block from 10K to 25K [more THROUGHPUT]
-- Block header verification in peer discovery (this was a MAJOR flaw in the last version) ... prevents sybill attacks as long as >10% nodes are honest in the network.
-- Ability to browse and view transactions in MemPool (Web UX)

No future forks will happen from this point on -- not that I have a say in the matter: once the nodes are running in the wild it is off to the races and no longer in my hands.

Thank you all for supporting my endeavor. It was a lot of work to write a new crypto codebase from the ground up -- especially for a single developer but I think it's finally coming close to release ready.

The next release will include:

MINER:
Windows binary + sources
Mac OSX binary + sources
Linux binary + sources

CLI WALLET:
Windows binary + sources
Mac OSX binary + sources
Linux binary + sources

NODE SERVER:
Mac OSX binary + sources
Linux binary + sources


Next up on the roadmap:

1. Release the Windows/Linux/MacOSX GUI Wallet
2. Improved Block Explorer that can show all transactions for a wallet etc.

Realistically these last two items will take until mid Feb to complete.
member
Activity: 328
Merit: 27
REALLY NICE update on the miner  Shocked

Good job on adding multithread, and periodic report!

I am the only one getting a good amount of rejected? (about 25-28% on avg)

Not just you, it just means the chain is ahead of us, so our block is orphaned, that is what rejected means. Those other miners have a bigger hashrate. (more than 51% so it becomes the valid chain/block)
jr. member
Activity: 70
Merit: 4
REALLY NICE update on the miner  Shocked

Good job on adding multithread, and periodic report!

I am the only one getting a good amount of rejected? (about 25-28% on avg)
member
Activity: 61
Merit: 17
The easiest way to send coins right now on Linux is with the cli:

make cli
./bin/cli

This will lookup the keys.json file to determine the coins source. It will ask for to wallet address, amount, tx fees and then send the transaction to the network. Transactions should be pretty reliable once the mempool fix I've been so busy implementing. It's ready and tested on the test net and will push this weekend.


Re: blocks... yes it has gotten more difficult...  it seems like there is some competition on the network. We're getting consistent 15-20 sec block times at a difficulty of 34. Based on Github stats we're getting 15-16 clones per day so the competition is definitely higher if that many folks are running the miner.



*** UPDATE *** We just pushed a change that will break your Miner when there is a non-empty block .... if you have not pulled from the latest version of master or are using the Linux/Mac OSX/Windows  binaries. I'll post new versions of the binaries later tonight but in the meantime we will see an increase in block times when transactions are present until all miners update to a compatible miner version as the old miner will fail to mine blocks with the new transaction format. Not a huge deal if you don't update your miner as there aren't that many transactions on the network yet.
jr. member
Activity: 70
Merit: 4
UPDATE: Miner source code now updated to use fast SHA256 implementation lifted from : https://github.com/ckolivas/cgminer
This will increase hashrate by 2x.

@Salamande: It is available via CLI and there is a wallet for Mac OSX. I think the CLI is not in perfect condition right now but if you'd like to transfer coins I can patch it up. Transactions on the network are a little iffy right now because of how the mem pool is implemented (if your transaction doesn't go through in a specified block it gets discarded). You can transact but it might require 3-4 attempts to get a transaction through. This is currently the highest priority update for me before public launch.
Mac OSX wallet:
https://github.com/mr-pandabear/panda-gui/releases/download/0.1.0-alpha/PandaWallet-MacOSX.zip

What platform are you using?




I'm using Linux for now.

Another question:

Seems like I don't get blocks anymore? Also tried the windows miner, same thing? Nothing in the last 24hr
member
Activity: 61
Merit: 17
UPDATE: Miner source code now updated to use fast SHA256 implementation lifted from : https://github.com/ckolivas/cgminer
This will increase hashrate by 2x.

@Salamande: It is available via CLI and there is a wallet for Mac OSX. I think the CLI is not in perfect condition right now but if you'd like to transfer coins I can patch it up. Transactions on the network are a little iffy right now because of how the mem pool is implemented (if your transaction doesn't go through in a specified block it gets discarded). You can transact but it might require 3-4 attempts to get a transaction through. This is currently the highest priority update for me before public launch.
Mac OSX wallet:
https://github.com/mr-pandabear/panda-gui/releases/download/0.1.0-alpha/PandaWallet-MacOSX.zip

What platform are you using?


jr. member
Activity: 70
Merit: 4
Is there some wallet functions implemented? Ex: sending coins
member
Activity: 61
Merit: 17
Okay! Finally we have Windows miner binaries available:
https://github.com/mr-pandabear/panda-coin/files/7709628/win32_release_binaries.zip

As stated before:
Run keygen.exe, this generates a keys.json file in the same folder as miner.exe, copy this file and keep it safe.
Run miner.exe, the miner will start running and should indicate that it is loading blocks to solve.

You may need to disable Windows defender if you get alerts starting it up -- sometimes it wrongfully labels the binaries as viruses.
Pages:
Jump to: