[bitcoin-dev] [BIP] OP_CHECKPRIVPUBPAIR

2015-11-27 Thread Mats Jerratsch via bitcoin-dev
Prior discussion:
http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-November/000309.html

Goal:
Greatly improve security for payment networks like the 'Lightning
Network' (LN) [1]

---

Introduction:
To improve privacy while using a payment network, it is possible to
use onion-routing to make a payment to someone. In this context,
onion-routing means encrypting the data about subsequent hops in a way
that each node only knows where it received a payment from and the
direct next node it should send the payment to. This way we can route
a payment over N nodes, and none of these will know

(1) at which position it is within the route (first, middle, last?)

(2) which node initially issued the payment (payer)

(3) which node consumes the payment (payee).

However, given the way payments in LN work, each payment is uniquely
identifiable by a preimage-hash pair R-H. H is included in the output
script of the commit transaction, such that the payment is enforceable
if you ever get to know the preimage R.

In a payment network each node makes a promise to pay the next node,
if they can produce R. They can pass on the payment, as they know that
they can enforce the payment from a previous node using the same
preimage R. This severely damages privacy, as it lowers the amount of
nodes an attacker has to control to gain information about payer and
payee.

---

Problem:
The problem was inherited by using RIPEMD-160 for preimage-hash
construction. For any cryptographic hash-function it is fundamentally
unfeasible to correlate preimage and hash in such a way, that

F1(R1) = R2 and
F2(H1) = H2, while
SHA(R1) = H1 and SHA(R2) = H2.

In other words, I cannot give a node H1 and H2 and ask it to receive
my payment using H1, but pass it on using H2, as the node has no way
of verifying it can produce R1 out of the R2 it will receive. If it
cannot produce R1, it is unable to enforce my part of the contract.

---

Solution:
While above functions are merely impossible to construct for a
cryptographic hash functions, they are trivial when R and H is a EC
private/public key pair. The original sender can make a payment using
H1 and pass on a random number M1, such that the node can calculate a
new public key

H2 = H1 + M1.

When he later receives the private key R2, he can construct

R1 = R2 - M1

to be able to enforce the other payment. M1 can be passed on in the
onion object, such that each node can only see M for that hop.
Furthermore, it is unfeasible to brute-force, given a sufficiently
large number M.

---

Example:

Given that E wants to receive a payment from A, payable to H. (if A
can produce R, it can be used as a prove he made the payment and E
received it)

A decides to route the payment over the nodes B, C and D. A uses four
numbers M1...M4 to calculate H1...H4. The following payments then take
place

A->B using H4
B->C using H3
C->D using H2
D->E using H1.

When E receives H1, he can use attached M1 to calculate R1 from it.
The chain will resolve itself, and A is able to calculate R using
M1...M4. It also means that all privacy is at the sole discretion of
the sender, and that not even the original pair R/H is known to any of
the nodes.

To improve privacy, E could also be a rendezvous point chosen by the
real receiver of the payment, similar constructions are similar in
that direction as well.

---

Caveats:

Currently it is difficult to enforce a payment to a private-public key
pair on the blockchain. While there exists OP_HASH160 OP_EQUAL to
enforce a payment to a hash, the same does not hold true for EC keys.
To make above possible we would therefore need some easy way to force
a private key, given a public key. This could be done by using one of
the unused OP_NOP codes, which will verify

  OP_CHECKPRIVPUBPAIR

and fails if these are not correlated or NOP otherwise. Would need
OP_2DROP afterwards. This would allow deployment using a softfork.

As there are requests for all sort of general crypto operations in
script, we can also introduce a new general OP_CRYPTO and prepend one
byte for the operation, so

0x01 OP_CRYPTO = OP_CHECKPRIVPUBPAIR
0x02-0xff OP_CRYPTO = OP_NOP

to allow for extension at some later point.

---

Alternatives:

In the attached discussion there are some constructions that would
allow breaking the signature scheme, but they are either very large in
script language or expensive to calculate. Given that the blocksize is
a difficult topic already, it would not be beneficial to have a 400B+
for each open payment in case one party breaches the contract. (or
just disappears for a couple of days)

It is also possible to use a NIZKP - more specifically SNARK - to
prove to one node that it is able to recover a preimage R1 = R2 XOR
M1, given only H1, H2 and M1. However, these are expensive to
calculate and experimental in it's current state.

---

Acknowledgements:
Gregory Maxwell for pointing out addition of M1 for EC points is much
less expensive
Pieter Wuille for helping with general under

Re: [bitcoin-dev] Alternative name for CHECKSEQUENCEVERIFY (BIP112)

2015-11-27 Thread Jorge Timón via bitcoin-dev
On Nov 26, 2015 12:06 AM, "Mark Friedenbach via bitcoin-dev" <
bitcoin-dev@lists.linuxfoundation.org> wrote:
> Again my objection would go away if we renamed nSequence, but I actually
think the nSequence name is better...

I suggested to rename nSequence to nMaturity on this list even before the
bips and implementations were started, probably too late now.
Before the implementation "let's think about those naming details later".
After the implementation "now it's too late, now we would need to change
the implementation, this renaming is now unnecessarily disruptive".

Reminds me of refactors and major releases:
At the beginning of the release "not now, this will disrupt development of
feature X"
After feature X is merged or replaced by feature Y: "too late in the
release cycle, refactors should be done only at the beginning, at the end
is 'too risky' ".
Sigh, I hope I find the "right time" (not both too soon and too late like
this time), next time...
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Alternative name for CHECKSEQUENCEVERIFY (BIP112)

2015-11-27 Thread Eric Lombrozo via bitcoin-dev
After reading Rusty's post, I admit there's something to be said for the fact 
that both the script and the nSequence field play a combined role, and thus, 
making the interaction between the two more clear in the naming make sense.

It is somewhat unfortunate that currently, we can't just have a dedicated field 
for the purpose of relative locktime (or minimum age) without having to 
repurpose the only unused 32 bits in the txin.

HOWEVER...there might be ways around this issue using segwit.

I've been pondering the possibility of adding an extra input vector to the 
prunable extra data that  comprises the witness. Witness structures can provide 
additional data that is used in transaction validation but does not contribute 
to the tx hash.

Currently, the signature checking opcodes in the script already do this 
implicitly for computing the hash that is signed (but not the tx hash used in 
block merkletrees)...and this is the principal cause of undesirable 
malleability issues. Clearly the signatures themselves cannot contribute to the 
hash they are signing. So segwit makes this separation explicit by moving the 
signatures to a structure external to the script. Pieter Wuille's 
implementation (https://github.com/sipa/bitcoin/tree/segwit) generalizes this 
idea using a script witness structure that is a vector of arbitrary inputs. 
Clearly moving the signatures into such structure is an important feature...but 
other types of input to the script could be placed here as well.

I had considered the possibility of placing a minimum age (relative locktime) 
field in the input vector that could be checked for mempool acceptance without 
having to evaluate the script. Of course, the location of such a field would 
have to be known by the mempool and cannot be an arbitrary element of a generic 
input vector, which adds some minor but surmountable complications.

Greg Maxwell pointed out, however, that signing opcodes that sign hashes 
discarding this data would make it trivial for anyone to change this field 
without signing anything. The nSequence fields of txins, being part of the tx 
serialization that gets hashed, is therefore always signed.

This led me to consider the possibility of adding extra opcodes to the script 
that can incorporate additional data in the hash that gets signed. This data 
would go in another structure that does not contribute to the tx hash but is 
outside the witness. Then we could add extra prunable data fields that the 
signer can commit to.

If I've missed something critical in the above analysis, someone please correct 
me...but it seems that such a mechanism would allow adding extra prunable 
signed data fields to transactions, which might ultimately remove scarcity of 
tx data that we can repurpose via soft forks. If this is the case, I would 
suggest turning the nSequence field into a dedicated min age/rlt field to 
simplify the semantics and avoid ugliness in trying to reclaim unused bits.

I may be overlooking something important here, but unless there's a reason such 
data cannot be made prunable, I haven't been able to poke a hole yet.

- Eric



On November 26, 2015 8:02:45 PM PST, Rusty Russell  
wrote:
>Eric Lombrozo via bitcoin-dev 
>writes:
>>>From an app developer's perspective, I think it is pretty blatantly 
>> clear that relative timelock is *the* critical exposed functionality 
>> intended here.
>
>As someone who actually developed scripts using CSV, I agree with Mark
>(and Matt).  The relative locktime stuff isn't in this opcode, it's in
>the nSequence calculation.
>
>So, I vote to keep CSV called as it is.
>
>Thanks,
>Rusty.
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev