Re: [Bitcoin-development] [softfork proposal] Strict DER signatures

2015-01-21 Thread David Vorick
Seems like a good change to me.

On Wed, Jan 21, 2015 at 7:32 PM, Rusty Russell ru...@rustcorp.com.au
wrote:

 Pieter Wuille pieter.wui...@gmail.com writes:
  Hello everyone,
 
  We've been aware of the risk of depending on OpenSSL for consensus
  rules for a while, and were trying to get rid of this as part of BIP
  62 (malleability protection), which was however postponed due to
  unforeseen complexities. The recent evens (see the thread titled
  OpenSSL 1.0.0p / 1.0.1k incompatible, causes blockchain rejection.
  on this mailing list) have made it clear that the problem is very
  real, however, and I would prefer to have a fundamental solution for
  it sooner rather than later.

 OK, I worked up a clearer (but more verbose) version with fewer
 magic numbers.  More importantly, feel free to steal the test cases.

 One weirdness is the restriction on maximum total length, rather than a
 32 byte (33 with 0-prepad) limit on signatures themselves.

 Apologies for my babytalk C++.  Am sure there's a neater way.

 /* Licensed under Creative Commons zero (public domain). */
 #include vector
 #include cstdlib
 #include cassert

 #ifdef CLARIFY
 bool ConsumeByte(const std::vectorunsigned char sig, size_t off,
  unsigned int val)
 {
 if (off = sig.size()) return false;

 val = sig[off++];
 return true;
 }

 bool ConsumeTypeByte(const std::vectorunsigned char sig, size_t off,
  unsigned int t)
 {
 unsigned int type;
 if (!ConsumeByte(sig, off, type)) return false;

 return (type == t);
 }

 bool ConsumeNonZeroLength(const std::vectorunsigned char sig, size_t
 off,
   unsigned int len)
 {
 if (!ConsumeByte(sig, off, len)) return false;

 // Zero-length integers are not allowed.
 return (len != 0);
 }

 bool ConsumeNumber(const std::vectorunsigned char sig, size_t off,
unsigned int len)
 {
 // Length of number should be within signature.
 if (off + len  sig.size()) return false;

 // Negative numbers are not allowed.
 if (sig[off]  0x80) return false;

 // Zero bytes at the start are not allowed, unless it would
 // otherwise be interpreted as a negative number.
 if (len  1  (sig[off] == 0x00)  !(sig[off+1]  0x80)) return
 false;

 // Consume number itself.
 off += len;
 return true;
 }

 // Consume a DER encoded integer, update off if successful.
 bool ConsumeDERInteger(const std::vectorunsigned char sig, size_t off)
 {
 unsigned int len;

 // Type byte must be integer
 if (!ConsumeTypeByte(sig, off, 0x02)) return false;
 if (!ConsumeNonZeroLength(sig, off, len)) return false;
 // Now the BE encoded value itself.
 if (!ConsumeNumber(sig, off, len)) return false;

 return true;
 }

 bool IsValidSignatureEncoding(const std::vectorunsigned char sig) {
 // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
 [sighash]
 // * total-length: 1-byte length descriptor of everything that follows,
 // excluding the sighash byte.
 // * R-length: 1-byte length descriptor of the R value that follows.
 // * R: arbitrary-length big-endian encoded R value. It cannot start
 with any
 // null bytes, unless the first byte that follows is 0x80 or
 higher, in which
 // case a single null byte is required.
 // * S-length: 1-byte length descriptor of the S value that follows.
 // * S: arbitrary-length big-endian encoded S value. The same rules
 apply.
 // * sighash: 1-byte value indicating what data is hashed.

 // Accept empty signature as correctly encoded (but invalid) signature,
 // even though it is not strictly DER.
 if (sig.size() == 0) return true;

 // Maximum size constraint.
 if (sig.size()  73) return false;

 size_t off = 0;

 // A signature is of type compound.
 if (!ConsumeTypeByte(sig, off, 0x30)) return false;

 unsigned int len;
 if (!ConsumeNonZeroLength(sig, off, len)) return false;

 // Make sure the length covers the rest (except sighash).
 if (len + 1 != sig.size() - off) return false;

 // Check R value.
 if (!ConsumeDERInteger(sig, off)) return false;

 // Check S value.
 if (!ConsumeDERInteger(sig, off)) return false;

 // There should exactly one byte left (the sighash).
 return off + 1 == sig.size() ? true : false;
 }
 #else
 bool IsValidSignatureEncoding(const std::vectorunsigned char sig) {
 // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
 [sighash]
 // * total-length: 1-byte length descriptor of everything that follows,
 // excluding the sighash byte.
 // * R-length: 1-byte length descriptor of the R value that follows.
 // * R: arbitrary-length big-endian encoded R value. It must use the
 shortest
 // possible encoding for a positive integers (which means no null
 bytes at
 // the start, except a single one when the next byte 

Re: [Bitcoin-development] Merge mining

2014-01-04 Thread David Vorick
If you have the resources to attack one of the bigger altcoins, you
probably have a significant investment in the cryptocurrency space, and a
significant interest in protecting it. Compromising even something like
dogecoin would cause a lot of questions to be raised and likely drop the
value of bitcoin as well as all the cryptocurrencies using the same work
function as dogecoin.

Right now, there's very little benefit to attacking a significant currency,
because it would be very expensive and likely traumatize the whole system.
Unless it's some power like the NSA, I don't think there's much to worry
about.


On Tue, Dec 31, 2013 at 2:38 AM, rob.gold...@astutium.com wrote:

  But there's so much 'dry powder' out there (GPUs), I wonder if *not*
  supporting merge-mining is any better? At least the attacker has to do
  some unique PoW, so you hope it's costing them something.

 With lots of people having access to 100TH+ there's not really much
 'cost' to doing a 51% attack on an alt-coin beyond a short-term
 diversion away from 'profitable' mining.

 At least by supporting merged mining, more miners are likely to
 'support' multiple coin types, thus making a 51% attack from an
 individual/group less straightforward.

  The rational decision for a non-scam altcoin, is to take advantage of
  merged mining to get as much security as possible.

 Exactly.

 Rob


 --
 Rapidly troubleshoot problems before they affect your business. Most IT
 organizations don't have a clear picture of how application performance
 affects their revenue. With AppDynamics, you get 100% visibility into your
 Java,.NET,  PHP application. Start your 15-day FREE TRIAL of AppDynamics
 Pro!
 http://pubads.g.doubleclick.net/gampad/clk?id=84349831iu=/4140/ostg.clktrk
 ___
 Bitcoin-development mailing list
 Bitcoin-development@lists.sourceforge.net
 https://lists.sourceforge.net/lists/listinfo/bitcoin-development

--
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET,  PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831iu=/4140/ostg.clktrk___
Bitcoin-development mailing list
Bitcoin-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bitcoin-development


Re: [Bitcoin-development] Double Spend Notification

2013-05-21 Thread David Vorick
I've been wondering why a blockchain is necessary at all. Ripple doesn't
have one (I haven't looked closely at their implementation but it seems
reasonable to go without one).

When you do blockchain based transaction confirmations, you give full
authority to the miner that finds the transaction block. That miner gets to
decide which transactions are real and which transactions are fraudulent,
and even has the option to not include any particular transaction (maybe
they used dirty coins, or something like that). The advantage to using a
blockchain is that any tough decisions to choose between two conflicting
transactions can be decided in an easy manner. The person who finds the
next block picks their favorite and tells everybody else.

But this has a huge downside: network confirmation can take more than 10
minutes (for an unlucky block). If you really want to be certain, a
confirmation can take more than an hour (multi-block confirmations).

For a transaction with no conflict, the network should be able to confirm
the transaction within a few seconds, because the information can propagate
to all of the nodes that quickly. The new issue is that if conflicting
transactions appear on opposite sides of the network, there needs to be
some way for the network to determine which transaction gets priority.
Right now the method is to wait for a miner to find a block and then go
with his decision, but perhaps there's some way to resolve a double spend
conflict without waiting for a block.

All you really need is for 51% of the nodes in the network to confirm a
transaction as legitimate in order for it to be 'confirmed' by the entire
network. Malicious nodes (nodes that confirm both conflicting transactions,
or nodes that refuse to confirm a transaction even though there are no
conflicts) can be excommunicated. The two challenges then would be

1. telling everybody when a transaction has hit 51% confirmation
2. dealing with a triple-or-more spend: A has 25% confirmation, B has 40%
confirmation, C has 35% confirmation, who wins?

For the first problem, each node only needs to see the transaction twice:
once when the node sees it for the first time and confirms it, and a second
time after the transaction hits 51% and is announced to the network as
confirmed. The first node to see the transaction hit 51% will make the
announcement.

The second problem could be reduced to a majority-wins problem. If a node
sees that 94% of votes are in, and one of the transactions is more than 6%
ahead of the others, that transaction is the winner.

If for whatever reason a clear majority is not hit by the time the next
mining block is found, the miner could just choose the transaction that had
the most votes when it saw it. It may be outdated but would clear up any
issues. This delay would only occur for a transaction if the spender of the
coins was attempting a double spend, and would indicate dishonesty to the
merchants. They could then choose to wait and see if their account is the
winner or they could just refuse to give out their goods.


On Tue, May 21, 2013 at 9:05 AM, Peter Todd p...@petertodd.org wrote:

 On Mon, May 20, 2013 at 08:54:25PM -0700, Gregory Maxwell wrote:
  One point that was only recently exposed to me is that replacement
  combined with child-pays-for-parent creates a new kind of double spend
  _defense_: If someone double spends a payment to an online key of
  yours, you can instantly produce a child transaction that pays 100% of
  the double spend to fees... so a double spender can hurt you but not
  profit from it.  (and if your side of the transaction is
  potentially/partially reversible he will lose)...

 You can do better than that actually: you can arrange the transaction
 such that the double-spender is hurt by asking them to pay an excess on
 top of the initial payment, and having that excess get returned to them
 in a subsequent transaction. Of course, that's trusting the merchant,
 but you're trusting the merchant to ship to a product anyway so...

 A really interesting example for this though would be applications where
 you are making a deposit. You credit the customer account immediately
 with half of the deposit amount, allowing them to immediately spend that
 portion for something transferable. (perhaps an alt-coin) If the
 customer tries to double-spend you burn half to fees, still leaving the
 other half to pay for what they did spend. If they don't double-spend,
 the rest of the balance becomes available after n confirmations. A
 BTC-alt-coin exchange could use this mechanism for instance, although
 it only works with widespread replace-by-fee adoption; blockchain.info's
 shared-send service is another application, as is SatoshiDice. (the
 failed bet tx can be the refund)

 What's nice here is even if the customer tries to pay a miner to do the
 dirty work, a short-term rational miner still has an incentive to screw
 over the customer by accepting the merchant's double-spend. Now the