1

Do I have to worry about endian swapping when calculating ECDSA public key values, Creation & Signing of transactions and verification of signature?

This question is more of a straightforward yes/no kind of question because as far as I can tell Bitcoin endianness swapping madness will make you feel like your logic & algorithm are incorrect... Which in a way is true when considering that the algorithm requires bit swapping on almost every turn...

So let's say I have functions

string CreateTransaction(); 
string SignTransaction();
bool VerifySignature(string Signature, vector<string> PublicKey);
string GeneratePublicKey(BigInteger PrivateKey, vector<string> &PublicKey);



// Takes input parameters like amount in Satoshi, receiving address
// and other necessary data as required by bitcoin protocol
string CreateTransaction(); // returns raw transaction hash


// Signs transaction as instructed by BIP rules | DER format
string SignTransaction(); // returns signature string


// Verifies received signature via parameter 
bool VerifySignature(string Signature, vector<string> PublicKey); // returns true is signature matches given x point of publicKey


// Generates publicKey via ECDSA Secp256k1 protocol
string GeneratePublicKey(BigInteger PrivateKey, vector<string> &PublicKey); // updated PublicKey address but returns compressed or Uncompressed public key value (Decimal or hexadecimal) 

I know for certain that the CreateTransaction(); requires endian swapping

But I'd just like to confirm if there is any point in time during the secp256k1 ECDSA curve calculation that I need to swap endianness of any data.

Because I don't require swapping endianness when carrying out HASH160() on a privateKey value to get an accurate hash.

1 Answer 1

0

All values required for your calculations are stored in big-endian format in the transactions. Where 'big-endian' basically means: you write it as you are used to writing down numbers, starting with the highest value digits. This goes for:

  • The x-coord and y-coord of publickeys
  • The r and s value of signatures
  • Also the result of the sha256(sha256(...)) when calculating a transaction hash.
  • Also the result of the sha256(sha256(...)) when calculating a message hash, to be used for signing.

Also, the hashes stored are in the 'normal' order, as what is specified in the original sha256 algorithm.

  • The source transaction hash used to reference the output.
  • The parent block hash.
  • The merkle root.

That is the sha256 algorithm as it is used outside of bitcoin.

This also holds for the ripemd160(sha256(...)) algorithm. And the way you convert an address hash to it's base58 representation uses big-endian numbers. The address itself is the big endian representation of the hash.

Only the way block and transaction hashes are commonly displayed is with the bytes of the hash reversed. So the 'real' hash of the genesis block is:

  • first step: af42031e805ff493a07341e2f74ff58149d22ab9ba19f61343e2c86c71c5d66d
  • second step: 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000

So basically, you only worry about swappig the endianness, when you print the transaction or blockhash for a person to view. Otherwise they stay as they are.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.