A lot of people were freaking out about a “Satoshi” signature validating. For those that know enough to check a signature, this signature does appear to validate. But how did this person do it? Does the Tweet actually have a valid signature?

“Satoshi” signature from a now-deleted Tweet

In this article, I go through the actual mathematical technique being used and why this “signature” is really a fake.

Some Red Flags

The first thing that clued many people into this being not up to snuff was the fact that this account didn’t use the standard sign/verify feature found in almost every Bitcoin wallet. Further, Faketoshi decided to release their own verification software, which is highly unusual. What happened? Why use something brand new? As the next section will show, this was entirely to mislead people.

Some Math

The actual math is not going to be understandable without a grasp of Finite Fields, Elliptic Curves and ECDSA. The links are to my new book, currently in technical review, but if you don’t want to learn about the math, feel free to skip this section.

Major kudos to Andy Poelstra, Greg Maxwell and Pieter Wuille for this code snippet, which I’ve made use of to come up with my own code and “signature”.

Note that in the above tweet H(m) = z , Rx = r and S = s in my construction below.

An ECDSA signature used in Bitcoin has two components, r and s , which sign the hash, z , of the some message with a public key P . The signature verification formula is:

u = z/s

v = r/s

R = uG+vP

if R.x = r , we have a valid signature

The way a signature is verified is that the z and P are already known to the verifier. If instead, the z is supplied by the signer, this essentially gives the signer enough degrees of freedom to produce a “valid” signature as pointed out in this tweet by Pieter Wuille:

a and b in Pieter’s tweet are u and v in my construction

Here’s how we can create such a nonsense signature. We start with a random u and a random v and work backwards. We can derive what r should be in order to make the signature valid:

R = uG+vP

r = R.x

Then, we designate:

s = r/v , which comes from v = r/s as per the validation formula

, which comes from as per the validation formula z = us , which comes from u = z/s as per the validation formula

Thus, the r , s and z from this construction will create u and v which will pass verification. The key here is that we got to select the z and that we had more degrees of freedom than a signer should be allowed.

Here’s some Python code to make this process clearer (ecc.py is from chapter 4 of my book):

from ecc import S256Point, Signature, G, N

from random import randint

# 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b

GENESIS_BLOCK_PUBKEY = '04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'

point = S256Point.parse(bytes.fromhex(GENESIS_BLOCK_PUBKEY)) # key from genesis block coinbase transactionGENESIS_BLOCK_PUBKEY = '04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'point = S256Point.parse(bytes.fromhex(GENESIS_BLOCK_PUBKEY)) # generate random u and v values

# (these will be different every time this script is run)

u = randint(0, N)

v = randint(0, N)



# calculate the x-coordinate of r

r = (u*G+v*point).x.num % N



# calculate s and z using Fermat's Little Theorem

s = r * pow(v, N-2, N) % N

z = u * s % N



# instantiate the Signature class

sig = Signature(r, s)



# This will crash if the signature is invalid:

assert point.verify(z, sig) is True



print("Valid signature of a garbage message:")

print("z: ", z)

print(sig)

The z , of course, is the hash digest of the message being signed. But if we can pick our own z instead of having to sign an intelligible message, we can produce these signatures at will.

To be clear, this Faketoshi wasn’t sophisticated enough to actually use a random v . The scammer used v=-1 , which makes this scam even more obvious.

Doing the same thing

The supposed “signature” from the “Satoshi” Tweet was nothing more than a trick that’s easy to expose with a little bit of a math. To prove it, here’s my “signature” using Satoshi’s genesis block public key (I used u=1, v=1 ):

z = d20a8b8b4d25086d71f03358d26d8564fc199aefd2a0239c49e9ab4c93a7025e

sec = 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f

der = 3046022100d20a8b8b4d25086d71f03358d26d8564fc199aefd2a0239c49e9ab4c93a7025e022100d20a8b8b4d25086d71f03358d26d8564fc199aefd2a0239c49e9ab4c93a7025e

This signature isn’t real because the message I signed is nonsense. Neither is the signature from the archived Tweet real.

Conclusion

The Tweet is equivalent to someone that’s “proving” that they ran a marathon in under 2 hours while allowing us to only observe them at the finish line. The nonsense signature is equivalent to someone “running” a marathon in under 2 hours by starting close to the finish line.

What’s even worse is that Calvin Ayre tweeted that the nonsense signature “proves” Satoshi lives.

This is nothing less than a fraud to sway unsophisticated investors.

A real signature would have the digital equivalent of an observable race starting line, so if someone wants to prove they possess Satoshi’s genesis key, here’s my challenge. Sign this message:

The Times 19/11/2018 The ups and downs of Downing Street

z = 2e1d1cc2a4ca52c6f6178570da8375365bc06416b898eb9436f328a4eb72d22d

There’s a reason Faketoshi refused to use the normal sign/verify protocol built into many Bitcoin wallets. The reason was to try to deceive people with trickery. If a signature is not signing an intelligible message, it is a scam, nothing more.

Want to learn more about Bitcoin programming including the code covered in this post? Sign up for my course in Sydney or Las Vegas!