Avatar
nick
91dbab9f62660e95258480d2f2cff6dcfdb513f28a85fa4fb55ee993a5b46809
peer-to-peer cash security

Has been great discussing this - got me thinking deeply and I found a bug in one of our cryptography libraries while exploring valid secp256k1 points! I haven't looked into knots really, semi dismissed it a while ago when i first saw this nuts counting system was supported(?)

https://en.bitcoin.it/wiki/Tonal_Bitcoin

Yeah not sure i am convinced of the reasons in that issue to **not** filter these, but i am thinking there may be value to the fact that this filter could be created at any time in the future, clear out a large chunk of the UTXO set after they have wasted their sats. Depends if how bad you consider the spam, is it about utxoset bloat or want to filter their existence in blocks

̶b̶l̶o̶c̶k̶ ̶t̶e̶m̶p̶l̶a̶t̶e̶ ̶c̶o̶n̶s̶t̶r̶u̶c̶t̶i̶o̶n̶

applied square packing theory

But many addresses are a hash of the public key, so we cannot validate the public keys when transactions are paying money to them. For these addresses it is impossible to filter based on public key until it is revealed, at time of spending, which requires them to be real and not spam!

Though I haven't thought about this wrt P2TR, and was somewhat surprised to see point validity isn't enforced:

https://github.com/bitcoin/bitcoin/pull/24106

I think id rather the spammers use invalid secp points! A nice broom to have up the sleeve? Can easily patch into a node to sweep out all the invalid ones from the utxoset.

It is super easy to generate these "fake" secp256k1 points which are valid:

02b33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33f

```rust

use rand::{RngCore, thread_rng};

use secp256kfun::{

Point, hex,

marker::{NonZero, Public},

};

fn main() {

let mut rng = thread_rng();

let hex_str = "b33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33fb33f";

let hex_bytes = hex::decode(hex_str).expect("invalid hex string");

loop {

let mut random_bytes = [0u8; 64];

rng.fill_bytes(&mut random_bytes);

let my_point_bytes = {

let mut bytes = [0u8; 33];

bytes[0] = 0x02; // start with 02

let hex_len = hex_bytes.len().min(32);

bytes[1..1 + hex_len].copy_from_slice(&hex_bytes[0..hex_len]);

// fill the rest with random bytes

if hex_len < 32 {

bytes[1 + hex_len..33].copy_from_slice(&random_bytes[0..32 - hex_len]);

}

bytes

};

let point = Point::<_, Public, NonZero>::from_bytes(my_point_bytes);

match point {

Some(valid_point) => {

println!("Random valid point: {:?}", valid_point);

}

None => {

eprintln!("Invalid point from bytes: {}", hex::encode(&my_point_bytes));

}

}

}

}

```

Replying to Avatar ESE

You can verify it yourself here:

https://onecompiler.com/python/43gy82we6

The first address fails the Base58Check checksum, so it’s not valid. The second one passes and decodes to a proper version 0 (P2PKH) hash.

Ah im an idiot i accidentally added an additional character at the front of the top one, it passes if you include it (11wizSAYSbuyXbt9d8JV8ytm5q69NaCfJ).

As do all these

"1WizSAYSbuyXbt9d8JV8ytm5q663tk94u",

"1WizSAYSbuyXbt9d8JV8ytm5q69PymsLb",

"1WizSAYSbuyXbt9d8JV8ytm5q69PymsLb",

And these (your npub padded by 1s)

"1Npub1w78wrepa4wz5odvqLq1112PjcmD",

"1HfeL834gv3282grjeg5cw2e6311CxBVx",

"1Eqszny2ms2jovtt111czzzzzzzywryfu"

Huge respect for posting code 🔥

Mine can be found here

https://utxo.club/base58.js

AHH completely out of control now 🥲

Yeah! Anywhere along the transmission from wallet to sender, can be clipboard malware (most common) where you copy an address and the malware pastes in a similar but different address, or browser malware which substitutes addresses within web requests (after you hit withdraw on an exchange), or malicious QR code scanner, or intercepted during unencrypted message transmission like you say.

Software wallet is indeed a domain you control, can verify signatures etc. The other stages are less in your control.

Not so much, though we've received a lot of feedback during our demos. It's easy to notice when someone is confused, often means we need to redesign something!

We've had so much to work with based on our own experiences as bitcoin users, but we're almost getting to the point where we have exhausted+resolved our personal painpoints. Much more user testing coming soon!

Replying to Avatar Noshole

https://v.nostr.build/EtjkMdAcu3zYKMCh.mp4

nostr:note1lwu0xv94hqz8s32m8zruhp3fks66nhr7saul5d35td79g0cc8waqnf9j2p

now this is zontent

Or are you referring to something else? Is there an occurrence of public keys which arent valid secp256k1 points?

What math?

Does this address pass your validation?

11wizSAYSbuyXbt9d8JV8ytm5q69NaCfJ

How about this one?

1wizSAYSbuyXbt9d8JV8ytm5acqq2TorC

Anything special about them? Most workflows don't guide the user with respect to the what and why afaik

ah so it wasnt only me who noticed that stream of bs flow through 😅

poor poor op return bot

Another tricky one is is geographic distribution of multisignature keys, there's little personal security gained if you keep a quorum of keys in one location!

I've designed a workflow to encourage geographic separation of each device alongside their respective backup, but it's still rough around the edges.. Some users may want to sit down and create all their backups at once, but then there's risk that they mix them up or get lazy and never distribute them into separate locations.

One that has been on my mind lately is verifying addresses on a hardware wallet when receiving funds.

It's rather ugly (big string of characters), so we chunk the address up and highlight some chunks at random.

It's also unintuitive, best practice is not to simply check that the address you're giving out from your software wallet matches the address derived on your hardware wallet. Since it could be intercepted and replaced during transmission (this is where most attacks are, clipboard malware).

Rather, you want to check that the **sender** sees the same address as displayed on your hardware wallet. Making the workflow and describing this is rather tricky, it all depends on who you're receiving from - is it an in-person transaction (compare visually)? is it over DMs (ask can you see the address chunks)? Is it a withdrawal from an exchange (compare against confirmation email, if provided)?

Designing bitcoin tools for a general audience people is insanely challenging

I could probably just rsync over ssh straight up, but git pulling acts as some reasonable version management making sure i don't publish some half-finished version

rsyncing only the important files to /var/www/ , can't be that guy that leaks .env 😅

deploying with ssh git pull and rsync

no slop required

steady lads

Enjoying this boomer rock rally because it gives me another angle to yap about hard money onto deaf ears

Might accidentally make an entire end-to-end ecommerce platform for purposes of customer privacy and checkout uptime...