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 ...
You are using the eliptic curve function of openssl and providing a serialized bytestring as an input. DER (Distinguished Encoding Rules) is a restricted variant of BER for producing unequivocal transfer syntax for data structures described by ASN.1.
The ASN1 structure for a privkey looks like this:
# ASN.1 STRUCTURE FOR PRIVATE KEY:
# 30 <-- ...
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 ...
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. ...
These magic values:
Openssl seems to use these values for DER encoding rules, and it doesn't seem to have anything to do with secp256k1 or Bitcoin specifically. Is this a correct assumption?
They have nothing to do with Bitcoin, but I believe that those bytes contain a reference to secp256k1 (probably through ...
Which kind of address do you want?
Assuming that you have compressed public key(compressed_public_key.txt), to generate P2PKH you can use these commands (hash160 and encoding with base58)
ADDR_RIPEMD160=$(printf $(cat compressed_public_key.txt | xxd -r -p | openssl sha256| sed 's/^.* //') |xxd -r -p | openssl ripemd160 | sed 's/^.* //')
The problem is that you are doing all of the hashing (and putting it into hex) and then having OpenSSL hash it again. openssl dgst will hash the message before signing, but this is incorrect for Bitcoin. Traditionally, in ECDSA, the message is hashed once and then signed. But with Bitcoin, it is actually hashed twice. Another way to think of this is that the ...
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, ...
How can i convert this (preferably using bash/Perl/python) into a WIF that can be imported into (preferably) Electrum?
OpenSSL .pem files contain base-64 encoding of the values encoded using DER. In case of private keys they use PKCS#8 explained in RFC5208. To extract the key itself, you first have to decode the base-64 string and get the key out by reading ...
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 ...
The version number is sort of arbitrary and up to the client, so long as the number chosen is valid.
The nLockTime is usually set to the current block height in modern wallets, this is a simple protection against a specific issue in Bitcoin called "fee sniping", where it is more economical to orphan other people's blocks to steal the fee income ...
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 ...