Pages:
Author

Topic: BIP 322 draft design and improvement thread (Read 1118 times)

brand new
Activity: 0
Merit: 0
copper member
Activity: 821
Merit: 1992
September 28, 2024, 09:51:26 AM
#64
Quote
Is BIP-322 a failure case?
Well, it is used in Signet. If you compare, what is signed in Signet blocks, and what message is signed by this BIP, then you will note, that they are similar.

Quote
Is it unfinished and isn't there any conclusion?
My conclusion is, that if you start a new regtest node, mine some coins on the desired outputs, and then ask someone, to sign specifically those outputs, then you will get roughly the same outcome, as you can get from this BIP, but easier, and with already working implementation.
member
Activity: 143
Merit: 82
September 28, 2024, 03:44:57 AM
#63
Is BIP-322 a failure case? Is it unfinished and isn't there any conclusion?

Quote
BIP322 is already merged, but as far as I am aware has not been deployed in any software. I do not know the reasons but work on it seems to have stopped. I would suggest that you reach out to the bitcoin developer mailing list if you would like to find out more or make an attempt to restart progress.
(https://github.com/bitcoin/bips/pull/1347#issuecomment-2092033174).

There is "simple" variant (taggedHash "BIP0322-signed-message") implemented in Sparrow: https://github.com/sparrowwallet/drongo/blob/f8f50c0dd907fac674ea363443b96772b6a0b658/src/main/java/com/sparrowwallet/drongo/crypto/Bip322.java#L18
and
https://github.com/ACken2/bip322-js
and
https://docs.rs/bip322/0.0.7/bip322/.
Anywhere else?

(I haven't verified if the implementations above are compatible).

I am grateful to aliashraf for thoughtful analysis and suggestions.
copper member
Activity: 900
Merit: 2243
Quote
Currently, I haven't found any way to sign a message with a n-of-m multi-sig (n != m).
In general, if you can sign a message with a single key, then you can do so with multiple keys, just by including multiple signatures. For example:
Code:
importdescriptors "[{\"desc\":\"pkh(cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA)#rpv80xem\",\"timestamp\":\"now\",\"label\":\"key\"}]"
importdescriptors "[{\"desc\":\"pkh(cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87K7XCyj5v)#fpg83s6d\",\"timestamp\":\"now\",\"label\":\"key2\"}]"

signmessage "mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r" "Hello World"
IGXH085B9ZEWwQqpO/zC9gtJZVES7DgLOHPONO5mbvCqXPI91aSz+/pYk/HK4w6NSYuzxgRi3qmNs/bTz9Pjr1o=
signmessage "mg8Jz5776UdyiYcBb9Z873NTozEiADRW5H" "Hello World"
IJ94zR6cD8snDDM2MlR4kXkr7WyaFbokViNC1pDAFfBDDMiI7ZlvD3Gbl2zKXw+DrprYB8DwI4fV5xPKNWh/sDw=

verifymessage "mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r" "IGXH085B9ZEWwQqpO/zC9gtJZVES7DgLOHPONO5mbvCqXPI91aSz+/pYk/HK4w6NSYuzxgRi3qmNs/bTz9Pjr1o=" "Hello World"
true
verifymessage "mg8Jz5776UdyiYcBb9Z873NTozEiADRW5H" "IJ94zR6cD8snDDM2MlR4kXkr7WyaFbokViNC1pDAFfBDDMiI7ZlvD3Gbl2zKXw+DrprYB8DwI4fV5xPKNWh/sDw=" "Hello World"
true
And then, you can say that both keys were used to sign the message "Hello World". But I think, using regtest transactions may be a better idea, because it provides more context into what is actually signed. Because in the classical "Bitcoin Message", you have to make sure, that signed data cannot be manipulated, and are for example committed to the public key. Because in other cases, you may also have valid signatures, created from unknown keys:
Code:
verifymessage "mgLpgMeX3LHzB11iUW3qfowPdVdgWYodGy" "GwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE=" "Hello World"
true
newbie
Activity: 16
Merit: 10
Thanks for your response. I've been requested in the Github BIP 322 thread to forward this to the mailing list. I've taken care of it.

It is possible, but tedious. If you can sign some message with a single key, then you can do it with multiple keys, just by providing N signatures. Unless you deploy N-of-N multisig, wrapped in Taproot address, then a single signature is sufficient.

If you have any information or bitcointalk post about it, please let me know. Currently, I haven't found any way to sign a message with a n-of-m multi-sig (n != m).

[EDIT]
Here is the discussion on the Bitcoin mailing list: https://groups.google.com/g/bitcoindev/c/RCi1Exs0ZvQ
copper member
Activity: 821
Merit: 1992
@vjudeu: I think some example is worth sharing:

Quote
you can run regtest
Code:
./bitcoin-qt -regtest

Quote
mine 101 blocks
Code:
generatetodescriptor 101 "raw(51)#8lvh9jxk"

Quote
move the coinbase reward from the first block into the output with the same script (this is your "to_spend" transaction)
This is our coinbase transaction for the first block. It will be identical for those commands above, only block headers may be different, but it doesn't matter in our use case:
Code:
decoderawtransaction 020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025100ffffffff0200f2052a0100000001510000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
{
  "txid": "b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101",
  "hash": "8afd56e9e7ddc7760553b4d75eb197f674921297a8d25c8a67dd171393810603",
  "version": 2,
  "size": 146,
  "vsize": 119,
  "weight": 476,
  "locktime": 0,
  "vin": [
    {
      "coinbase": "5100",
      "txinwitness": [
        "0000000000000000000000000000000000000000000000000000000000000000"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 50.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "1",
        "desc": "raw(51)#8lvh9jxk",
        "hex": "51",
        "type": "nonstandard"
      }
    },
    {
      "value": 0.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_RETURN aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9",
        "desc": "raw(6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9)#cav96mf3",
        "hex": "6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9",
        "type": "nulldata"
      }
    }
  ]
}
We import some kind of descriptor, which we want to use. For example, this is 2-of-2 multisig with the first two public keys, with well-known private keys:
Code:
importdescriptors "[{\"desc\":\"wsh(multi(2,cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA,cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87K7XCyj5v))#yp9440fj\",\"timestamp\":\"now\",\"label\":\"multisig\"}]"
Then, we can get our destination address for that descriptor:
Code:
getaddressesbylabel "multisig"
{
  "bcrt1qnwvyc7aw8m7acw3lpgs0lqdlaz0drls8luf72cs5nmn9f0kcghdsr03hg4": {
    "purpose": "receive"
  }
}
Now, we can send those coins into that output:
Code:
createrawtransaction "[{\"txid\":\"b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101\",\"vout\":0}]" "[{\"bcrt1qnwvyc7aw8m7acw3lpgs0lqdlaz0drls8luf72cs5nmn9f0kcghdsr03hg4\":0.00000000}]" 0 true
02000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0100000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db00000000
This is sufficient as our "to_spend" transaction. But we can add something more, and put for example some OP_RETURN, and describe here the purpose of our signature, include SHA-256 of some message to be signed, or do anything else. For example, if we want to sign an empty message, then we can do it like that:
Code:
SHA-256("")=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
SHA-256(0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)=5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456
createrawtransaction "[{\"txid\":\"b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101\",\"vout\":0}]" "[{\"bcrt1qnwvyc7aw8m7acw3lpgs0lqdlaz0drls8luf72cs5nmn9f0kcghdsr03hg4\":0.00000000},{\"data\":\"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456\"}]" 0 true
02000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0200000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db0000000000000000226a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945600000000
And then, when we decode it, we can check, if we are satisfied with our "to_spend" transaction or not:
Code:
decoderawtransaction 02000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0200000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db0000000000000000226a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945600000000
{
  "txid": "13f688efceedf677e3498a764e9ba0b8dcb744e77afa2bb5e5b3eb23e1005531",
  "hash": "13f688efceedf677e3498a764e9ba0b8dcb744e77afa2bb5e5b3eb23e1005531",
  "version": 2,
  "size": 137,
  "vsize": 137,
  "weight": 548,
  "locktime": 0,
  "vin": [
    {
      "txid": "b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "sequence": 4294967293
    }
  ],
  "vout": [
    {
      "value": 0.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 9b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db",
        "desc": "addr(bcrt1qnwvyc7aw8m7acw3lpgs0lqdlaz0drls8luf72cs5nmn9f0kcghdsr03hg4)#sncal8mg",
        "hex": "00209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db",
        "address": "bcrt1qnwvyc7aw8m7acw3lpgs0lqdlaz0drls8luf72cs5nmn9f0kcghdsr03hg4",
        "type": "witness_v0_scripthash"
      }
    },
    {
      "value": 0.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_RETURN 5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456",
        "desc": "raw(6a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456)#d92ky5p2",
        "hex": "6a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456",
        "type": "nulldata"
      }
    }
  ]
}
Quote
and then spend it (this is your "to_sign" transaction)
Code:
createrawtransaction "[{\"txid\":\"13f688efceedf677e3498a764e9ba0b8dcb744e77afa2bb5e5b3eb23e1005531\",\"vout\":0}]" "[{\"data\":\"00\"}]" 0 true
0200000001315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a010000000000
decoderawtransaction 0200000001315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a010000000000
{
  "txid": "b607fce6ad2f066fc7f44da0242bf34ae5bc3356ad0cd2f0ab80c02b9146b15d",
  "hash": "b607fce6ad2f066fc7f44da0242bf34ae5bc3356ad0cd2f0ab80c02b9146b15d",
  "version": 2,
  "size": 63,
  "vsize": 63,
  "weight": 252,
  "locktime": 0,
  "vin": [
    {
      "txid": "13f688efceedf677e3498a764e9ba0b8dcb744e77afa2bb5e5b3eb23e1005531",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "sequence": 4294967293
    }
  ],
  "vout": [
    {
      "value": 0.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_RETURN 0",
        "desc": "raw(6a0100)#80h597s4",
        "hex": "6a0100",
        "type": "nulldata"
      }
    }
  ]
}
We are almost there. The first transaction is something, which is ready to be broadcasted, because it spends some input with OP_TRUE, so we don't have to sign it (but we can pick a different coinbase script, to have well-separated networks, if we need it). The second one is something, which can be signed as usual:
Code:
signrawtransactionwithwallet "0200000001315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a010000000000" "[{\"txid\":\"13f688efceedf677e3498a764e9ba0b8dcb744e77afa2bb5e5b3eb23e1005531\",\"vout\":0,\"scriptPubKey\":\"00209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db\",\"amount\":0.00000000}]"
{
  "hex": "02000000000101315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a01000400473044022052e36a84fd710284a5cc7dfef5f0b2ceb3d8040fb2b0246dec6b047cda0558bc02201d1417dfd5f365979bf48b8ac1270620b7f8d61c1d9f5469dabe6504d5f42fb201473044022024dfa28b7b862a77e3b8e5932c701f48611c807442af58a647044b49d5ce9b46022048b21abd7a00b90f84a4add20708ae6646b06f7192ebb00bd62555a799c5b3eb014752210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee552ae00000000",
  "complete": true
}
So, we got it. Now, we mine a new block with both transactions to see, if they will be included or not:
Code:
generateblock "raw(51)#8lvh9jxk" "[\"02000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0200000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db0000000000000000226a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945600000000\",\"02000000000101315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a01000400473044022052e36a84fd710284a5cc7dfef5f0b2ceb3d8040fb2b0246dec6b047cda0558bc02201d1417dfd5f365979bf48b8ac1270620b7f8d61c1d9f5469dabe6504d5f42fb201473044022024dfa28b7b862a77e3b8e5932c701f48611c807442af58a647044b49d5ce9b46022048b21abd7a00b90f84a4add20708ae6646b06f7192ebb00bd62555a799c5b3eb014752210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee552ae00000000\"]"
{
  "hash": "33d04181986f72e6eb6ec242038ccc771ab91737824842af7e8b59fc2b1e062e"
}
And then, we can get our block:
Code:
getblock 33d04181986f72e6eb6ec242038ccc771ab91737824842af7e8b59fc2b1e062e 0
00000020835d62e738fa39592a010cec55ecf2893fe34892366a0b16d4412b8145f8265d87e0b04d65bc32299be9c2a3d7e2e4893f611be09e838a23e9f5b6e85063d78974d33366ffff7f200000000003020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016600ffffffff0200f2052a0100000001510000000000000000266a24aa21a9ed82c0bae1305d92344ce05f23f4ae166f8fb643ff66105e9653e0f27213ab068e012000000000000000000000000000000000000000000000000000000000000000000000000002000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0200000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db0000000000000000226a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c94560000000002000000000101315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a01000400473044022052e36a84fd710284a5cc7dfef5f0b2ceb3d8040fb2b0246dec6b047cda0558bc02201d1417dfd5f365979bf48b8ac1270620b7f8d61c1d9f5469dabe6504d5f42fb201473044022024dfa28b7b862a77e3b8e5932c701f48611c807442af58a647044b49d5ce9b46022048b21abd7a00b90f84a4add20708ae6646b06f7192ebb00bd62555a799c5b3eb014752210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee552ae00000000
Voila. This is our signature. For the recipient, we have to share only the first, and the last command. Which means, that if you want to verify a signature, then all you have to do, is to execute those two commands in some empty regtest network:
Code:
generatetodescriptor 101 "raw(51)#8lvh9jxk"
generateblock "raw(51)#8lvh9jxk" "[\"02000000010101811a9245cfae75af3f2fb5ebebb35ee25dfee53b74afac6a45be242bbab40000000000fdffffff0200000000000000002200209b984c7bae3efddc3a3f0a20ff81bfe89ed1fe07ff13e562149ee654bed845db0000000000000000226a205df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c945600000000\",\"02000000000101315500e123ebb3e5b52bfa7ae744b7dcb8a09b4e768a49e377f6edceef88f6130000000000fdffffff010000000000000000036a01000400473044022052e36a84fd710284a5cc7dfef5f0b2ceb3d8040fb2b0246dec6b047cda0558bc02201d1417dfd5f365979bf48b8ac1270620b7f8d61c1d9f5469dabe6504d5f42fb201473044022024dfa28b7b862a77e3b8e5932c701f48611c807442af58a647044b49d5ce9b46022048b21abd7a00b90f84a4add20708ae6646b06f7192ebb00bd62555a799c5b3eb014752210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982102c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee552ae00000000\"]"
{
  "hash": "3f87546d0aa236dd53d9900658768bc975af30eaadba65d5b7b78a2a653374f2"
}
As you can see, the hash of the block will be different each time, mainly because of timestamps. But: if you explore the contents of the block, then it contains exactly the same "to_spend" and "to_sign" transactions. And if you import your multisig descriptor, you will see your "to_spend" transaction in the GUI (if you want to also see "to_sign" transaction, then you have to add some additional output, which will contain one of the keys from your wallet).
Code:
importdescriptors "[{\"desc\":\"wsh(multi(2,cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA,cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87K7XCyj5v))#yp9440fj\",\"timestamp\":\"now\",\"label\":\"multisig\"}]"
So, as you can see, you can create some transactions, which are similar to BIP-322, even if slightly different, if you just use regtest for that purpose. And I think it should meet most of your requirements, as long as BIP-322 is not finished.
copper member
Activity: 900
Merit: 2243
Quote
If there's no response the next few weeks, I will send an e-mail to the Google Group mailing list about our use-case.
I guess you can send it now. Messages in the mailing list are published with a delay, because they are reviewed, and accepted by humans. Which means, that even if you send it now, then don't be surprised, if it will be published tomorrow, or three days later. It is normal. Some people are surprised, and think, that "hey, they censored my message", but very often it is not the case, and the message is later published.

Quote
However, as you know, it's currently impossible to sign a message with a multi-sig wallet.
It is possible, but tedious. If you can sign some message with a single key, then you can do it with multiple keys, just by providing N signatures. Unless you deploy N-of-N multisig, wrapped in Taproot address, then a single signature is sufficient.

Quote
I'm unsure why BIP322 hasn't been pushed or addressed in the past few months/years, but I want to highlight its necessity.
The reason is quite simple: writing code is hard. It requires time and knowledge. And if you have an Open Source world, then people spend their free time, usually without any reward, and they implement things, as they see fit. So, if that was not yet urgently needed by anyone, or if those who needed it, used simple workarounds like "just produce N classical Bitcoin Messages for each public key separately", then just nobody was determined enough, to finish it.

Also note, that there are some workarounds, which are close to BIP-322, but have just slightly different format. For example: you can run regtest, mine 101 blocks, move the coinbase reward from the first block into the output with the same script (this is your "to_spend" transaction), and then spend it (this is your "to_sign" transaction). Then, you share those two transactions, and if your recipient will have the same regtest setup, with the same 101 initial blocks, it can simply send raw transactions, mine a new block, and see, if it is valid or not.
newbie
Activity: 16
Merit: 10
Hey,

I just wanted to let you know that I commented this thread on Github: https://github.com/bitcoin/bips/pull/1347#issuecomment-2090701376

If there's no response the next few weeks, I will send an e-mail to the Google Group mailing list about our use-case.

@ProfEduStream
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
On the other side, I thought Kallewoof was following this BIP322 thread. If he does not, sending this use-case in an e-mail is a good idea.

No he isn't. In fact all the important technical stuff is being discussed in this pull request: https://github.com/bitcoin/bips/pull/1347 and on the bitcoin-dev mailing list.

Admittedly the proposal hasn't had much talk since around 2022.

Would you like to do it, considering your started this bitcointalk post? If not, I gonna send him an message this week. (Just so you know: I don't have his e-mail.)

I actually don't have his email address, or at least, I don't remember if I ever used email to contact him (It was mainly by Github). But you should be able to get an audience if you post this on the mailing list now that it's moved to Google Groups.
newbie
Activity: 16
Merit: 10
Indeed.

On one side, I gonna talk with 2 Bitcoin developpers in May about this use-case. Maybe will they talk further about it.

On the other side, I thought Kallewoof was following this BIP322 thread. If he does not, sending this use-case in an e-mail is a good idea.
Would you like to do it, considering your started this bitcointalk post? If not, I gonna send him an message this week. (Just so you know: I don't have his e-mail.)
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
The problem is that we use a multi-sig wallet, as some other associations and companies.
However, as I previously said, it's currently impossible to sign a message with a multi-sig wallet, 'cause BIP 322 hadn't been pushed for a few months / years.

It also means that we can't prove that we own an address by signing a message with our multi-sig wallet; which is an information asked in some regulated countries (in Switzerland for example). It's not a KYC thing, just a "proof of addresses ownership".


Not being able to sign a message with a multi-sig wallet is also a lack in our Bitcoin ecosystem, and I hope it gonna change in the next few weeks / months.

We are going to need to do a lot of advocating if we are to get any BIP merged into the Bitcoin protocol at this point. Nowadays the only things that are merged are stuff that gets many months of deliberations on the mailing list, and also it's going to need a working implementation and nobody can work that the way Kalle (the author) can.

I suggest sending your BIP322 use case as an email to him and that should generate at least some attention to the practical use of BIP322.
newbie
Activity: 16
Merit: 10
Hello guys,

In the past few weeks, I spent a few hours researching a way to sign a message with a multi-sig wallet. After a lot of tests, I discovered the Bitcoin #322 Proposal.


    
As a Bitcoin association, whose goal is to educate people about Bitcoin in our city, we enable everyone to become a member of our association for a few thousands sats per year. To do so, we use Swiss Bitcoin Pay.
It's an app' which enables us (and shops too) to export easily our accounting if needed. We also onboard merchants with this app', 'cause it's UX friendly, very easy to use too, self-custodial; and the accounting part is very usefull in lots of countries.


The problem is that we use a multi-sig wallet, as some other associations and companies.
However, as I previously said, it's currently impossible to sign a message with a multi-sig wallet, 'cause BIP 322 hadn't been pushed for a few months / years.

It also means that we can't prove that we own an address by signing a message with our multi-sig wallet; which is an information asked in some regulated countries (in Switzerland for example). It's not a KYC thing, just a "proof of addresses ownership".


Not being able to sign a message with a multi-sig wallet is also a lack in our Bitcoin ecosystem, and I hope it gonna change in the next few weeks / months.

    

Atm, I only spent a couple of hours learning about how Bitcoin signatures work.
My only discovery is that the ECDSA function is neither linear, nor commutative. If it was, the solution would have been very easy to implement.
Got a couple ideas, but I need to go further in my researches and understanding of ECDSA.


To sum up: if this thread (and BIP) was forgotten, please make it live again. We need that in our ecosystem.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
Bumping this as I got word that the BIP322 man himself (kalle) is lurking around, so collaborations on the design and implementation should be possible right now.  Smiley
legendary
Activity: 1456
Merit: 1175
Always remember the cause!
I just have one question about Taproot branches:

When you're making a witness stack, the public keys for the other cosigners don't need to be on the stack? [that's really the only way I see the keys being hidden, unless I'm missing something here.]


Yes, you can easily hide public keys that their exposure is not strictly necessary with MAST:
For 1 of n signatures, unlike legacy Bitcoin script, you will have n identical leafs such as OP_CHECKSIG for each pubkey.

To spend the P2TR outpoint, or for what you are interested in (proving to be relevant), holders of each key should include log2n - 1  hashes (Merkle path) and only their own public key, besides the signature as witness.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
Quote
Replace the message challenge of "to_spend" with a 1-of-N standard P2WPKH multisig. N is the number of people you want to be able to create the signature, and their respective pubkeys are included in the script.
Just use P2TR and reveal one of N TapScript branches, then all other public keys will remain hidden. Also, if you have 1-of-N, then you have two cases:
1) you don't care who signed the message
2) you want to know, who did it
In the first case, people could spend by key. In the second case, people could also spend by key, but include a commitment in R-value of their signature, then it would be possible to check, who signed that. Unless you want to force that, then you can force people to spend by script, and place N-of-N key to allow spending by key if all people will agree.

Yeah, like I said, this is a good idea and I will study how P2TR spending works. I just had a dive into BIP341 this morning, and there's a lot of stuff to go over in there.

I just have one question about Taproot branches:

When you're making a witness stack, the public keys for the other cosigners don't need to be on the stack? [that's really the only way I see the keys being hidden, unless I'm missing something here.]
copper member
Activity: 821
Merit: 1992
Quote
Replace the message challenge of "to_spend" with a 1-of-N standard P2WPKH multisig. N is the number of people you want to be able to create the signature, and their respective pubkeys are included in the script.
Just use P2TR and reveal one of N TapScript branches, then all other public keys will remain hidden. Also, if you have 1-of-N, then you have two cases:
1) you don't care who signed the message
2) you want to know, who did it
In the first case, people could spend by key. In the second case, people could also spend by key, but include a commitment in R-value of their signature, then it would be possible to check, who signed that. Unless you want to force that, then you can force people to spend by script, and place N-of-N key to allow spending by key if all people will agree.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
Alright, so maybe I won't need proxy signatures at all. Besides, that's going to take us dangerously close to altcoin-frontier. Here I have a not-so-private way of creating a signature delegations using only constructs already defined in the protocol. Not so private, because it uses multisig - all public keys are revealed. I was hoping that something like MuSig or key aggregation would help with this but its still a draft.

It is extremely simple and doesn't require any additional transactions:

- Replace the message challenge of "to_spend" with a 1-of-N standard P2WPKH multisig. N is the number of people you want to be able to create the signature, and their respective pubkeys are included in the script.
-- In this way the possible delegatees are fixed at signature creation time and cannot be extended by creating more transactions.
- Replace the challenge solution in "to_sign" (it's the input that spends the output we made in "to_spend") with a witness stack containing: n ... 1 0
-- The signature is generated as if it were for a real P2WPKH-multisig transaction. [the zero at the end is due to a bug in OP_CHECKMULTISIG that pops an extra element].

appendix - don't mix up this delegation and Full with UTXOs together - it increases the numebr of permutations that implementations have to verify.

Pros:

- No recursive transactions.
- Faketoshi cannot forge a signature that verifies successfully - he does not know any of the private keys in the multisig.
- The Address field is not used when delegating, so the engine can actually print which (compressed) public key it is signed against - i.e. the address verification is provable, as opposed to reactive Legacy signatures.
-- Additionally, they will all be Segwit Bech32 addresses so it can just derive and print the corresponding bc1 address instead.
- There is no opcode or new algorithm introduced, so no soft-fork is required.

Cons:

- Everyone knows the public keys of the delegators, so there is no privacy.



I am satisfied with this - barring any other complaints about BIP322, do you guys think this scheme is simpler than the one I made yesterday?
legendary
Activity: 1456
Merit: 1175
Always remember the cause!
Quote
what you are doing is bad for the resistance, it makes us to look weak and irrelevant, leaving bitcoin defenseless
Why? Bitcoin is so resistant to changes that sidechains should be introduced by no-forks, because they won't be accepted as a soft-fork. And this proposal is also a no-fork, so you can think about it in the same category as HD wallets and similar BIPs. Bitcoin is so resistant to changes that hard-forks are practically impossible to introduce, soft-forks are very hard to introduce, and you complain that Bitcoin is "defenseless"? The strongest defense is just sticking with what we have and rejecting any new proposals. And you know that people can always do that, and it will only escalate, so more no-forks will be needed to change anything.
It was a more general complaint regarding OP's extreme practicism (as I see it) not any specific topic. OP doesn't like questioning BIP322, feeling an obligation to implement it in a rush.

As for sidechains, well I'm a fan as long as they are not deviated from basics, for instance I wouldn't contribute to RSk because they have adopted Turing completeness which is inherently vulnerable, for instance check what is happening with Ethereum: only 2 or 3, besides Vitalik's Foundation, are in charge. Just check what the rock star says:
At the moment of the merge, you will have two [separate] networks […] and then you have exchanges, you have Oracle providers, you have stablecoin providers that are kind of deciding in a way, which one they respect.

It is what happens when you have Turing completeness and smart contracts full-blown, corporates decide everything, the decide who is allowed to fork or not to fork. The hilarious point about the situation with Ethereum is the fact that Vitalik and the gang are forking, not the other side!

It is what I believe in bitcoin to be colonized as its side chain, almost the exact same bitcoin, I mean.

copper member
Activity: 821
Merit: 1992
Quote
in the case of delegation, I look up @garlonicon's idea
It is based on vjudeu's idea: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019988.html
And he later also wrote more posts about that.

Quote
what you are doing is bad for the resistance, it makes us to look weak and irrelevant, leaving bitcoin defenseless
Why? Bitcoin is so resistant to changes that sidechains should be introduced by no-forks, because they won't be accepted as a soft-fork. And this proposal is also a no-fork, so you can think about it in the same category as HD wallets and similar BIPs. Bitcoin is so resistant to changes that hard-forks are practically impossible to introduce, soft-forks are very hard to introduce, and you complain that Bitcoin is "defenseless"? The strongest defense is just sticking with what we have and rejecting any new proposals. And you know that people can always do that, and it will only escalate, so more no-forks will be needed to change anything.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
~
Wandering in the woods is beyond any Bitcoiner. We are not hired by anybody, there is no obligation to follow TODO assignments by BIPs just because they've got some stupid number.
More importantly, your approach compromises the very first line of resistance for Bitcoin: dev resistance.

I feel, that while this scenario is entirely possible (provided that the adversiary somehow finds people who are willing to code and think*), we are doing a disservice to bitcoin by not making an effort to standardize parts.

*In the age of social media and tiktok, such people are rare - divide the number of posters in Dev&Tech discussion over the week, by the number of Bitcointalk users online within the last week - you get the idea.



This whole endeavor would've been unnecessary had my BIP just been numbered by luke-jr in the first place, but he didn't, and this is not the thread for me to rant about that. Decisions are decisions, and if the standardization for some part can only be done in a specific way, then I will push in that direction in the name of change (which I feel is infinitely more useful than me making a hundred posts in this thread).

I'm operating as a lone wolf - certainly, almost nobody else on this forum has the technical compretence to even do anything about these drafts (judging by the number of users who replied to this topic in the last 2 weeks). Sure, this implies you have to trust me not to fuck standards up, but I know, that I can definitely trust myself not to screw up, and to me that's all that really matters.

Sure, if delegation is not needed in the first place, somebody on the mailing list can speak up, and that'll be the end of it. But so far the mailing list has been almost radio silence for the past week except for myself. So I, an independent guy unaffiliated with the BIP, have no idea if any of the TODOs are still valid.

So this is the game plan now:

- in the case of delegation, I look up @garlonicon's idea. If that doesn't work out, I've already found a well-known cryptography construct called proxy signatures (Brave search link, only because google's was too long and DuckDuckGo has the search query in the POST data - ignore all results about HTTP proxies) that solves all these problems without supporting ugly recursion, so I make a BIP around that.
-- It will primarily be used by BIP322 if the author(s) can come at a decision about it.

And then I leave the problem alone, since everything is solved - no need for opcodes, Merkle Branches or any of that weird stuff in the other TODOs.

Quote
what you are doing is bad for the resistance, it makes us to look weak and irrelevant, leaving bitcoin defenseless.

Huh

Yes, I know about resistance to no-coiners. But in this parliament, there is no seat for them, since the community never elected them here in the first place. Therefore, all of their criticisms and attacks are irrelevant to us. There's a seat for you, there's a seat for me, seats for some of these other guys here, seats for mailing list posters, etc. because the community wants us (collectively) to discuss and find solutions for these matters.

Ultimately, nobody has execution power over BIPs that they did not author. I'm not an exception. I can't "force" anybody to include my suggestions in their own BIPs.
Pages:
Jump to: