Skip to content

Instantly share code, notes, and snippets.

@thejohnfreeman
Last active April 9, 2020 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejohnfreeman/1748a3910268f3c02b36f8409b7f6233 to your computer and use it in GitHub Desktop.
Save thejohnfreeman/1748a3910268f3c02b36f8409b7f6233 to your computer and use it in GitHub Desktop.
GROUP_ORDER = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'
// Divide by two and round up = shift right 1 bit and add 1.
HALF_GROUP_ORDER = '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A1'
function isFullyCanonical(signatureDer) {
s = signatureDer.slice(-32)
// A lexicographical compare between big-endian hex strings yields the same ordering
// as a comparision of the unsigned integers they represent.
return s < HALF_GROUP_ORDER
}
signatureDer = '30440220...'
isFullyCanonical(signatureDer)
@bachase
Copy link

bachase commented Apr 9, 2020

signatureDer is just hex string of the sig?

@thejohnfreeman
Copy link
Author

To be honest, it depends on how the signature is represented... The signature is two 32- or 33-byte numbers commonly named r and s. The normal DER encoding includes both of them, but there is a compressed encoding that takes only one byte from one of them, but I forget which. To judge full canonicalization we need the full s. Do you have an example from the database?

@thejohnfreeman
Copy link
Author

I'm remembering wrong. The public key is compressed, but the signature is not. So yes, signatureDer is just the hex string of the signature. There are multiple representations for the signature, but the one we use in XRPL is DER-encoded.

@bachase
Copy link

bachase commented Apr 9, 2020

Txn with hash 58F140BD9B4FB4160F4C2B3711F06E24F46C7085F8CF9A6FE119F93AEAC7B697 has signing public key
03D847C2DBED3ABF0453F71DCD7641989136277218DF516AD49519C9693F32727E and signature
304402207374724663A13CDF92CFAA9BAEFC085D3379E60B323DA445506398B19299ABE002203CD9826F711D0F378171B35105E79F4A346BBC8208402B6F866E509CD453F4F3

All these are bigquery SQL STRING types.

@thejohnfreeman
Copy link
Author

thejohnfreeman commented Apr 9, 2020

Yes. Let me break down the DER encoding of the signature:

  • 3044: sequence of (44 in base 16) = 68 bytes
  • 0220: integer of (20 in base 16) = 32 bytes (if a positive integer has 1 for the most-significant bit of its most-significant byte, it is prefixed with a zero byte 00)
  • ... 32 bytes of r ...
  • 0220: integer of (20 in base 16) = 32 bytes
  • ... 32 bytes of s ...

@shaelilwang
Copy link

Just so I understand -- for this example, s is after 0220. s in this case is 3CD9...F4F3, and a canonical sig because less than HALF_GROUP_ORDER? Should it be signatureDer.slice(-64) instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment