In particular, the seed key, but really this applies to both. I'm looking for the best way to validate that a key is formed correctly. I know it has 56 chars and starts with "S" for seeds and "G" for public keys, but is there a mask to validate it or I have to go look it up everytime?
2 Answers
If you are using Stellar JS SDK, the following method will work for you.
import StellarBase from 'stellar-base'
if (StellarBase.StrKey.isValidEd25519SecretSeed('SB....4A')) {
//secret key is valid
}
if (StellarBase.StrKey.isValidEd25519PublicKey('GA....6C')) {
//public key is valid
}
If you're just interested in checking whether it's a well-formed key, you can use the following algorithm:
- Verify that the string starts with "S"
- Base-32 decode the S... string to get the raw bytes. You will end up with 35 bytes.
- Ignore the first byte since it represents the "S".
- Calculate the CRC-16 checksum of the next 32 bytes. These bytes represent the ED25519 private key.
- Compare the CRC-16 checksum[1] you just generated to the last two bytes. If they don't match, the key was entered incorrectly.
The same algorithm can be used to verify the public account string (G...).
If you're interested in checking whether the account exists on the network, then you'll need to generate the public key and make a call to the Horizon API since there's no guarantee that a valid account is funded.
References:
- [1] Stellar uses the "XMODEM" version of CRC-16 with a start value of 0x0000 and a polynomial of 0x1021: http://mdfs.net/Info/Comp/Comms/CRC16.htm