Search content
Sort by

Showing 8 of 8 results by johndebord
Post
Topic
Board Development & Technical Discussion
Merits 1 from 1 user
Re: Is It Possible to Verify Participation In Aggregated Signatures
by
johndebord
on 06/12/2024, 07:27:29 UTC
⭐ Merited by vjudeu (1)
OP, what is the value of deterministicValue that you used for this line?

Code:
if (secp256k1_musig_nonce_gen(
        Secp256k1::context().get(), &secp256k1MusigSecretNonce,
        &secp256k1MusigPublicNonce, deterministicValue, nullptr,
        &secp256k1PublicKey, message, nullptr, nullptr) == 0) {
  throw std::runtime_error{"failed to generate nonces"};
}

Code:
if (secp256k1_musig_nonce_gen(
        Secp256k1::context().get(), &secp256k1MusigSecretNonce,
        &secp256k1MusigPublicNonce, masterPrivateKey, nullptr,
        &secp256k1PublicKey, messageHash, nullptr, nullptr) == 0) {
  throw std::runtime_error{"failed to generate nonces"};
}

In this case, the masterPrivateKey used is:

Code:
6942F99EDEE91D2B59780FC865016CC7F452973C3D7A8735AE9F76CAACB57C1A

It is important to note that everything is known except the full set of private/public key pairs that contributed to the aggregated signature or public key.
Post
Topic
Board Development & Technical Discussion
Re: Is It Possible to Verify Participation In Aggregated Signatures
by
johndebord
on 05/12/2024, 21:18:04 UTC
Thank you for the detailed insights and suggestions.

To make the discussion more concrete, I believe it would be best to present a practical example. This will outline all the data that is publicly available.

For clarity and practical implementation, I will use the data structures provided by the secp256k1 library.

Below is a general idea of how the data was generated. Note that this code is illustrative and not the exact implementation:

Code:
secp256k1_keypair secp256k1Keypair{};
if (secp256k1_keypair_create(
        Secp256k1::context().get(), &secp256k1Keypair, privateKey) == 0)
  throw std::runtime_error{"failed to create key pair"};
}
secp256k1_pubkey secp256k1PublicKey{};
if (secp256k1_keypair_pub(
        Secp256k1::context().get(), &secp256k1PublicKey,
        &secp256k1Keypair) == 0) {
  throw std::runtime_error{"failed to extract public key"};
}
secp256k1_musig_secnonce secp256k1MusigSecretNonce{};
secp256k1_musig_pubnonce secp256k1MusigPublicNonce{};
if (secp256k1_musig_nonce_gen(
        Secp256k1::context().get(), &secp256k1MusigSecretNonce,
        &secp256k1MusigPublicNonce, deterministicValue, nullptr,
        &secp256k1PublicKey, message, nullptr, nullptr) == 0) {
  throw std::runtime_error{"failed to generate nonces"};
}
secp256k1_musig_keyagg_cache secp256k1MusigKeyAggregationCache{};
// ... code to aggregate the public keys ...
secp256k1_musig_aggnonce secp256k1MusigAggregatedNonce{};
// ... code to aggregate the public nonces ...
secp256k1_musig_session secp256k1MusigSession{};
if (secp256k1_musig_nonce_process(
        Secp256k1::context().get(), &secp256k1MusigSession,
        &secp256k1MusigAggregatedNonce, message,
        &secp256k1MusigKeyAggregationCache) == 0) {
  throw std::runtime_error{"failed to process nonce"};
}
if (secp256k1_musig_partial_sign(
        Secp256k1::context().get(), &secp256k1MusigPartialSignature,
        &secp256k1MusigSecretNonce, &secp256k1Keypair,
        &secp256k1MusigKeyAggregationCache,
        &secp256k1MusigSession) == 0) {
  throw std::runtime_error{"failed to partially sign"};
}
const constexpr std::size_t schnorrSignatureSize{64};
CryptoArray<schnorrSignatureSize> aggregatedSignature{};
// ... code to aggregate the partial signatures ...
secp256k1_pubkey secp256k1AggregatedPublicKey;
if (secp256k1_musig_pubkey_get(
        Secp256k1::context().get(), &secp256k1AggregatedPublicKey,
        &secp256k1MusigKeyAggregationCache) == 0) {
  throw std::runtime_error{"failed to get aggregated public key"};
}
secp256k1_xonly_pubkey aggregatedSecp256k1XonlyPublicKey{};
if (secp256k1_xonly_pubkey_from_pubkey(
        Secp256k1::context().get(), &aggregatedSecp256k1XonlyPublicKey,
        nullptr, &secp256k1AggregatedPublicKey) == 0) {
  throw std::runtime_error{
      "failed to convert public key to xonly public key"};
}
if (secp256k1_schnorrsig_verify(
        Secp256k1::context().get(),
        reinterpret_cast<const std::uint8_t *>(
            aggregatedSignature.data()),
        message, message.size(),
        &aggregatedSecp256k1XonlyPublicKey) == 0) {
  throw std::runtime_error{"failed to verify signature"};
}

Here is the data generated for the example:

Code:
message: 45F8481247B5C84C48A9952CC7B9AA9B27EAD6A90B2D250E24F81152FB25DECE

Key Pair 1:
  privateKey: 6942F99EDEE91D2B59780FC865016CC7F452973C3D7A8735AE9F76CAACB57CCD
  secp256k1PublicKey: 02A3D48DC0B2BA69F340F68FB4D8BEEF5BE361FB64DAB71EF74ACCF6ACABF70B01
  secp256k1MusigPublicNonce: F57A3DA0D4A492010CF9777E237D4EA7005212072958248A624E761F70A0027AD78EB2A99784232661BEFD6CA2CF17517E49DAFFD7AA6C5BD69FE93A4FC841CB835123BC3404FB9CBEC7BA112C6D0F6800247DB3382619DA497D11E08869DD926DE9457DEF6E9B9197BD44A5DF599CD0260851F0707C693B8FBE58914C1A219BBE888765
  secp256k1MusigSecretNonce: 220EDCF13B5E1B766BF04082984E34CD17575158C7F7F25DC4A81D1C0A9A8E7E33CAD3BD00A362F6E9AF37DC10EAE6162C6FDF8C0074A050025CD1BB0D2BF14010DB8722010BF7ABACF6CC4AF71EB7DA64FB61E35BEFBED8B48FF640F369BAB2C08DD4A340C4EB116E73B2F1C7B4D2FB188BAB910934212CAF70F1175228FAC79D8F5488
  secp256k1MusigPartialSignature: EBFB1A3284DDE05BA570956916623030D11F266A8260A8C4F074190793F088E12EABB41F

Key Pair 2:
  privateKey: 6942F99EDEE91D2B59780FC865016CC7F452973C3D7A8735AE9F76CAACB57E4A
  secp256k1PublicKey: 027FA2874F02C66B1B7778FD178E8332CF113FDB5536F2005E83DD1F6E77037A89
  secp256k1MusigPublicNonce: F57A3DA05150DF05A15EE6CECB86218C9300090AF710EB2B8C6E51CBF3D0B8EB7235E240249F1B51F53F956FA4609B707AED531CCB37854A8FB9AB0E703CDB34BCABA310846018549CE3086CCB7BB0DC25ABB59D79205D918F6911EBF1B10AFE1516CB7F849E04BA945332881E13A3E5C63AC05120F52FABD248F03D5A5D45ECBEC37538
  secp256k1MusigSecretNonce: 220EDCF12372A9189B273F7EE4E6D63CF919F3735C93AE0D4898F2099F986CA572097D2BB6C5A742EDE67454BD1F20B2071A6772529F7EC8815E817BA33A51BFD9BD2B6A897A03776E1FDD835E00F23655DB3F11CF32838E17FD78771B6BC6024F87A27FF224968B7AE9ECD15FCE3965A05C6E90C78D8527F01744204BE48161B6FEA8C7
  secp256k1MusigPartialSignature: EBFB1A321C984FD7C278DC61F18C80A68DA4B231B08337C39A6F508E27EA184989190027

Key Pair 3:
  privateKey: 6942F99EDEE91D2B59780FC865016CC7F452973C3D7A8735AE9F76CAACB58011
  secp256k1PublicKey: 024CBBD03BC9B079BC360A26A034A298EB4520333F87DA4A3D195F390B50B7BD27
  secp256k1MusigPublicNonce: F57A3DA0D30E12A1367AE49B87EAA99FA678DEAD817221DBAC9BB0AFA70D9A08AB36B147D3B03A46C163E0401898FA6D209B6F139680A4E95D07A9A4E501106725C1671B8B916792FBE092441290E2300FC5C093DD40118D29DFF8F25A9C7413B4D86D26E75DAD92CD3A94455B9DDD94673F283B7E0438652FA5FCC91B03C3B44DA39130
  secp256k1MusigSecretNonce: 220EDCF1E48E62BE3329485818C71B5D129F0294E3C7E899AA584B6940FD9737CFDD2EE3483F714997C706C3F984E35CB405F869E3D477EA479E42B300C0EC82B145F0D027BDB7500B395F193D4ADA873F332045EB98A234A0260A36BC79B0C93BD0BB4C940202A0A14E78D617DD2CD39E62C10A2D43EBC66E5962179C7C85D062401979
  secp256k1MusigPartialSignature: EBFB1A32894F0D7D27ACE83FD53B0E14B3F65F963BB62F1F1F29B89B25E5DF3B96174160

Aggregated Data:
  secp256k1XonlyPublicKeyAggregated: 6BF1779F97025AFD66240B3CDDB97DED15B6D44902CBDC98FE8BA5E18F4F37A894B88F128CDDFB02C265154E17E30D09D82A5528F123046235124D34E2F8262C
  aggregatedSignature: BE99342E3F9A4F4EDC5815C90270B32D29DB7B7F65F39DE33FCFA82E9C19EA6B2AC53DB08F965A0ADD29BEEC12BA3833B3EB32C0FAC481F521EE21D97DA5B465

So, given the above data, what specific operations need to be performed to confirm that the public key: 024CBBD03BC9B079BC360A26A034A298EB4520333F87DA4A3D195F390B50B7BD27 contributed to the aggregated signature or the aggregated public key?
Post
Topic
Board Development & Technical Discussion
Merits 1 from 1 user
Re: Is It Possible to Verify Participation In Aggregated Signatures
by
johndebord
on 05/12/2024, 09:38:16 UTC
⭐ Merited by vjudeu (1)
I appreciate the responses so far. I realize my initial question wasn’t detailed enough, so I’d like to expand and clarify. I’m working with Schnorr signatures, specifically in the context of multisignatures.

Assume the following setup:

  • A publicly known message (it could be any message, or even empty).
  • The message is signed by 100 private/public key pairs, each using a deterministic nonce value.
  • The signatures are aggregated into a single aggregated signature.
  • The public keys are aggregated into a single aggregated public key.
  • All information is public except for the complete set of private/public key pairs that contributed to the aggregated signature and aggregated public key.

The question is: Given the available public information, is it possible to verify whether a specific private/public key pair contributed to the aggregated signature or whether a private/public key pair contributed to the aggregated public key?

If this verification is possible, how can I achieve it using the secp256k1 library?

From an earlier suggestion, it seems I might need to extract the s value from the 64-byte aggregated signature (which includes both R and s) and modify it appropriately. Additionally, I would need to remove the contribution of the specific public key (noting that the corresponding private key and nonce are known) from the aggregated public key, and then verify against the modified aggregated signature and the modified aggregated public key. Or is there a better method using the secp256k1 library? Any guidance would be greatly appreciated.
Post
Topic
Board Development & Technical Discussion
Merits 1 from 1 user
Topic OP
Is It Possible to Verify Participation In Aggregated Signatures
by
johndebord
on 30/11/2024, 07:26:19 UTC
⭐ Merited by vjudeu (1)
Suppose you have a message, and this message is signed by 100 private/public key pairs. The signatures are then aggregated into a single aggregated signature. Now, assume the only public information available is the aggregated signature, the original message, and one private/public key pair from the 100 key pairs used in creating the aggregated signature.

Is it possible to verify that this specific private/public key pair contributed to the aggregated signature, or is such verification impossible?
Post
Topic
Board Development & Technical Discussion
Re: Is It Possible to "Reserve" a Private Key?
by
johndebord
on 07/10/2024, 00:36:15 UTC
Thank you for the insightful responses. I’ll be looking into everything that’s been mentioned here. One point I’d like to clarify, though, is that in the protocol I’m working on, private key collisions are expected to be a regular occurrence. I understand this might seem unconventional.
Post
Topic
Board Development & Technical Discussion
Re: Is It Possible to "Reserve" a Private Key?
by
johndebord
on 06/10/2024, 20:29:50 UTC
I appreciate the insights and suggestions provided, especially regarding the process of signing messages to prove ownership of a private key. To further clarify, I'm working on a concept where proving the initial ownership of a private key is central to the protocol.

From my understanding, signing a message and including it on the blockchain is one of the simplest ways to demonstrate control over a private key. However, this raises an interesting question: in the event of a private key collision, where two different users independently generate the same private key and sign messages with it in the same block, wouldn’t that create a conflict? It seems like a situation analogous to a "double spend" or a "double reserve" of the same key. Both parties could claim ownership at the same time in the same block.

To mitigate this, I’m considering an alternative approach: instead of relying solely on signatures, what if ownership was demonstrated by allocating a minimal amount of Bitcoin (e.g., 1 satoshi) to the address derived from the private key? This would tie the private key to an on-chain transaction, with the balance of the associated address acting as proof of ownership. The protocol could then verify ownership by checking whether the address has a balance of 1 at the time of the claim or reservation.

Would this method be effective in preventing collisions or conflicts? And within the Bitcoin protocol, could this be scripted in a way that ensures compatibility with its existing framework? Or is there a better way?
Post
Topic
Board Development & Technical Discussion
Re: Is It Possible to "Reserve" a Private Key?
by
johndebord
on 06/10/2024, 07:16:41 UTC
I appreciate the responses and I understand the importance of keeping a private key secure and secret. However, I think my question may not have been fully clear.

What I’m asking is this: Is there a way to maintain ownership of a private key even when you intend to reveal it to someone else?

For example, let’s say my private key is 0101010101010101010101010101010101010101010101010101010101010101, and I choose to disclose this key to someone else. Given that I'm willingly revealing the private key, is there a method or technique that would allow me to maintain control or ownership over that key and any future funds associated with it? Or is it simply impossible to preserve ownership?
Post
Topic
Board Development & Technical Discussion
Topic OP
Is It Possible to "Reserve" a Private Key?
by
johndebord
on 05/10/2024, 18:29:49 UTC
Is it possible to "reserve" a private key? In other words, can someone select a private key and perform an action (such as creating a specific transaction or something else) that effectively claims or reserves that key?