Bitcoin uses ECDSA so ECDSA keypairs are Bitcoin keypairs as well.
echo "Generating private key"
openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -out $PRIVATE_KEY
This generates the private key in the pem format that openssl uses.
echo "Generating public key"
openssl ec -in $PRIVATE_KEY -pubout -out $PUBLIC_KEY
This generates the public key ...
Alternatively, you could use libsecp256k1. This is the code used by Bitcoin Core for signing, and will automatically create low-S signatures (disclaimer: I'm the main author of that library).
Perhaps a Go wrapper exists.
If you stick to OpenSSL, it is possible to manually adjust the S value after signing. This is what Bitcoin Core used to do before v0.10. ...
The code you are referring to in libsecp256k1 is not for ECDSA.
It implements the custom compact signatures that Bitcoin Core uses for message signing and verification.
The normal ECDSA code in libsecp256k1 should be identical in acceptance to the one in OpenSSL (apart from the fact that by default, it only accepts and produces low-s signatures, as a way ...
The ECDSA digital signature scheme returns two values. To be specific, the X and Y values computed on the elliptic curve are returned.
In Bitcoin the signture is DER encoded, which is represented as a string containing the X and Y values and also some header data. But both X and Y can easily be extracted from it when reading the string from left to right.
I fixed the issue by installing extra libraries, the whole list
sudo apt-get install -y autoconf g++ make openssl libssl-dev libcurl4-openssl-dev
sudo apt-get install -y libcurl4-openssl-dev pkg-config
sudo apt-get install -y libsasl2-dev
Generation of both PrivKey and PubKey:
openssl ecparam -genkey -name secp256k1 -text -noout -outform DER | xxd -p -c 1000 | sed 's/41534e31204f49443a20736563703235366b310a30740201010420/PrivKey: /' | sed 's/a00706052b8104000aa144034200/\'$'\nPubKey: /'
Gives following result:
The problem is that you are hashing the string of hex characters instead of the actual bytes that the hex string represents. You should be using an array instead with the bytes specified. The following should work:
string sha256(char str, size_t len)
unsigned char hash[SHA256_DIGEST_LENGTH];
You got the pubkey correct but at least one thing wrong and maybe more in the parts you didn't show.
First and fundamentally, bitcoin uses an unconventional (arguably nonstandard) scheme where the data is double-hashed before the nonceG,kinv(hash+nonceimage) calculation and corresponding verification.
dgst -sign/-verify only does the standard single hash, ...
The value r is just a number and doesn't explicitly store or encode any point coordinates. In a signature, r is set to the X coordinate of the point R, which is really k*G, where k is the secret nonce used during signing, then reduced mod the curve order.
In secp256k1, this usually means that r is in fact the X coordinate (because r itself is usually very ...
Open SSL won't force it, you will have to do it yourself. From BIP 62:
The value S in signatures must be between 0x1 and 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0 (inclusive). If S is too high, simply replace it by S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S.
I've found one bug in those shell scripts, though I'm not sure it's the only one. Once fixed, it's now generating the same sha256d's of the unsigned txs as another tool I've tried (before it was not).
If you look here, you'll see that the txin's scriptSig is getting properly set to the to-be-signed UTXO's scriptPubKey, however for the scriptPubKeys that ...