Bitcoin Forum
June 24, 2025, 02:03:03 AM *
News: Latest Bitcoin Core release: 29.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: New ashigaru whirlpool coordinator can de-anonymize users  (Read 100 times)
1440000bytes (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 23


View Profile WWW
June 23, 2025, 07:25:17 AM
Last edit: June 23, 2025, 09:01:18 AM by 1440000bytes
Merited by NotATether (6), d5000 (5), cAPSLOCK (5), theymos (2), DireWolfM14 (1)
 #1

Ashigaru announcement: https://ashigaru.rs/news/announcement-whirlpool/

https://i.ibb.co/Q7G2rDBr/rsa.png

Background: Nothingmuch had reported a vulnerability in whirlpool in December 2024: https://groups.google.com/g/bitcoindev/c/CbfbEGozG7c/m/w2B-RRdUCQAJ

This allows a malicious coordinator to link inputs and outputs by providing each input with a unique RSA public key. Since the unblinded signatures are possibly made by different keys, the server can learn the mapping from inputs to outputs.

The blind signing process requires a server or coordinator to share the public key. The highlighted text in the announcement is misleading. I looked at the code in Whirlpool-Client and Whirlpool-Server and found that the vulnerability is not fixed.

Code:

    // generate a secret bordereau. keep it private and register INPUT with blindedBordereau
    // bordereau will be provided with unblindedSignedBordereau to register POSTMIX with another
    // identity
    this.bordereau = ClientUtils.generateBordereau();
    byte[] publicKey = WhirlpoolProtocol.decodeBytes(confirmInputMixStatusNotification.publicKey64);
    RSAKeyParameters serverPublicKey = ClientUtils.publicKeyUnserialize(publicKey);
    this.blindingParams = clientCryptoService.computeBlindingParams(serverPublicKey);

    String mixId = confirmInputMixStatusNotification.mixId;
    String blindedBordereau64 =
        WhirlpoolProtocol.encodeBytes(clientCryptoService.blind(bordereau, blindingParams));
    String userHash = premixHandler.computeUserHash(mixId);
    ConfirmInputRequest confirmInputRequest =
        new ConfirmInputRequest(mixId, blindedBordereau64, userHash);

    confirmedInput = true;
    return confirmInputRequest;
  }


http://ashicodepbnpvslzsl2bz7l2pwrjvajgumgac423pp3y2deprbnzz7id.onion/Ashigaru/Ashigaru-Whirlpool-Client/src/commit/a64bd8b4e0ee8a4cfab03da4565f166d07caa7ec/src/main/java/com/samourai/whirlpool/client/mix/MixProcess.java

Code:

        // register confirming input
        String publicKey64 = WhirlpoolProtocol.encodeBytes(mix.getPublicKey());
        ConfirmInputMixStatusNotification confirmInputMixStatusNotification =
                new ConfirmInputMixStatusNotification(mix.getMixId(), publicKey64);
        mix.registerConfirmingInput(registeredInput);

http://ashicodepbnpvslzsl2bz7l2pwrjvajgumgac423pp3y2deprbnzz7id.onion/Ashigaru/Ashigaru-Whirlpool-Server/src/branch/main/src/main/java/com/samourai/whirlpool/server/services/MixService.java

Conclusion: Users should not trust this centralized coordinator and do their own research before paying 5% coordinator fees.
NotATether
Legendary
*
Offline Offline

Activity: 2002
Merit: 8637


Search? Try talksearch.io


View Profile WWW
June 23, 2025, 08:21:08 AM
 #2

We seriously need to make a dedicated website on github.io or something that lists all of the information related to coordinators, because it's fragmented everywhere at the moment.

People need to know which coordinators are safe to use.

Although I know this pertains only to whirlpool coordinators, I'm only aware of one running at the moment, ever since Samourai's was shut down.

██
██
██
██
██
██
██
██
██
██
██
██
██
... LIVECASINO.io    Play Live Games with up to 20% cashback!...██
██
██
██
██
██
██
██
██
██
██
██
██
1440000bytes (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 23


View Profile WWW
June 23, 2025, 02:18:47 PM
 #3

It seems they aren't using code from whirlpool-client repository in the terminal. Instead hardcoded a public key for signing:

Code:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp5iSNzsR0S77fby4CFkG
OHF2oKNKsAYyK8e8SEwQrqmheYHF2t3mRAoYa0iN1OUXqhl3AkN5pOZQxJosIUFL
GR2tVNtYFv0ehzxUwYWBTIFNblNysccayBlFwQMuZaCa7/Cz/MGuemmn9/tBh1Vp
7CxfYRYVXHlSe08cYImtVg6dtrcarw/rm24ke1siUxLnrM6/LbgCWfvR6SKTZ7Zm
Ox5pi0TRTkcL1dJli5QDkUA6sLFUxmvG03rZLJ61LFFqm495VLsRCHVT5jDHz5aK
Xljk9Hhe2II9iHiy3GRy+01w1ZvPZ6Am2mO1usgAu1J5Zilnt0ahxLEQB2wRnXTP
UQIDAQAB
-----END PUBLIC KEY-----


Code:

        // use receiveAddress as bordereau. keep it private, but transmit blindedBordereau
        // clear receiveAddress will be provided with unblindedSignedBordereau by connecting with
        // another identity for REGISTER_OUTPUT
        final RSAKeyParameters rsaPublicKey;
        byte[] publicKey = WhirlpoolProtocol.decodeBytes(confirmInputMixStatusNotification.publicKey64);
        if (publicKey != null && publicKey.length > 0) {
            throw new ProtocolException("not expected to receive public key for blind signature from whirlpool server");
            //rsaPublicKey = ClientUtils.publicKeyUnserialize(publicKey);
        } else {
            rsaPublicKey = blindSignaturePublicKey;
        }

        this.blindingParams = clientCryptoService.computeBlindingParams(rsaPublicKey);

        String mixId = confirmInputMixStatusNotification.mixId;
        this.bordereau = ClientUtils.generateBordereau();
        String blindedBordereau64 =
                WhirlpoolProtocol.encodeBytes(
                        clientCryptoService.blind(this.bordereau, blindingParams));
        String userHash = premixHandler.computeUserHash(mixId);
        ConfirmInputRequest confirmInputRequest =
                new ConfirmInputRequest(mixId, blindedBordereau64, userHash);

        confirmedInput = true;
        return confirmInputRequest;
    }


This introduces other issues in the coinjoin process. I will add more details after doing some research and testing.
dmatthewstewart
Sr. Member
****
Offline Offline

Activity: 444
Merit: 253



View Profile
June 23, 2025, 11:48:33 PM
 #4

They specifically mention this in their update. And there seems to be a coordinated effort across all platforms by the Wasabi fans to just pump FUD. It’s becoming very cultish.

Maybe you should’ve done your testing before making the post. You make a conclusion in your title that has not yet been tested.


1440000bytes (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 23


View Profile WWW
Today at 12:31:32 AM
 #5

1. The coordinator can link input-outputs even with the hardcoded key

The client doesn't verify that the unblinded signature is actually a valid RSA signature for the hardcoded public key. The coordinator can still do tagging and link inputs-outputs after output registration.

2.  New DoS vector is introduced in the code

If you confirm an input getting a blind sig, and then just time out, you can later use the same unblinded sig in a subsequent session and register an additional output which is a DoS issue.

Related tweets by nothingmuch: https://xcancel.com/not_nothingmuch/status/1937176085461930033
1440000bytes (OP)
Newbie
*
Offline Offline

Activity: 13
Merit: 23


View Profile WWW
Today at 12:39:56 AM
 #6

They specifically mention this in their update. And there seems to be a coordinated effort across all platforms by the Wasabi fans to just pump FUD. It’s becoming very cultish.

Maybe you should’ve done your testing before making the post. You make a conclusion in your title that has not yet been tested.


I am not associated with Wasabi. This is a free review and testing unlike others who trust the anonymous developers or not competent enough to review. Denying the bugs based on an announcement to use suboptimal tools sounds cultish.

The conclusion is still the same. Too many red flags to trust this coordinator and everyone should do their own research before wasting money in coordinator fees.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!