Skip to content

Instantly share code, notes, and snippets.

@thejohnfreeman
Created January 14, 2020 15:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejohnfreeman/519c0bdea684a8d41e6e8e7b03dbe426 to your computer and use it in GitHub Desktop.
Save thejohnfreeman/519c0bdea684a8d41e6e8e7b03dbe426 to your computer and use it in GitHub Desktop.
secp256k1
secp256k1 is just one popular curve for the Elliptic Curve Digital Signature algorithm (ECDSA).
An ECDSA key is a 256-bit value.
ECDSA will sign a 256-bit value.
If you want to sign a message of arbitrary length, it is customary to first hash the message to a 256-bit value.
One popular hash is SHA-256, but the one XRPL uses is "SHA-512 Half" (SHA-512 truncated to the first half, which is 256 bits).
ECDSA returns a point on a plane, whose coordinates are commonly named `r` and `s`.
Distinguished Encoding Rules (DER) is a popular encoding of a structure called Abstract Syntax Notation One (ASN.1).
ASN.1 can represent types like integers, sequences, and sets.
DER encodes these values to tag-length-value byte sequences.
ECDSA signatures (`r` and `s`) are customarily encoded with DER.
`r` and `s` are usually 32-byte integers (I've sometimes seen one of them be a 33-byte integer),
and they are concatenated in a sequence,
so their DER encoding is:
1-byte code for SEQUENCE (0x30)
1-byte length of sequence (0x01 + 0x01 + 0x20 + 0x01 + 0x01 + 0x20 = 0x44) +
1-byte code for INTEGER (0x02) + 1-byte for length of r (0x20) + r
1-byte code for INTEGER (0x02) + 1-byte for length of s (0x20) + s
or briefly: 0x3044 0220 r... 0220 s...
There are a few popular libraries for ECDSA in Python:
- `cryptography` from the Python Cryptographic Authority, a wrapper around OpenSSL
- `ecdsa`, a pure Python implementation
- `fastecdsa`, a wrapper around a custom implementation of ECDSA in C
There are two methods I need from a library:
1. Constructing a signing key object from a 256-bit value.
2. Signing a 256-bit message.
Each of these libraries supplies a `sign` method that signs an arbitrary-length message,
which means it is hiding a call to a hash function.
I believe all of them use the same default, SHA-256.
They all take a parameter for overriding the hash function.
If I'm supplying a 256-bit digest as the message to be signed, my hash function can be the identity function.
To perform some sanity checks on my use of a library, I need some known (key, message, signature) tuples.
It seems like the cryptography community calls these test vectors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment