w3c-ccg / did-method-key

DID (Decentralized Identifier) did:key method for embedding keys in DID urls
https://w3c-ccg.github.io/did-method-key
Other
18 stars 12 forks source link

Should this spec define byte prefixes associated with ASN.1 RSA Keys? #42

Open OR13 opened 2 years ago

OR13 commented 2 years ago

Originally reported here: https://github.com/w3c-ccg/did-method-key/pull/41#issuecomment-970379835

IMO, it's a nice to have, that would make is possible for some implementations to skip importing bulky ASN.1 libraries as @dlongley mentions.

clehner commented 2 years ago

I supposed that it would be simple (https://github.com/w3c-ccg/did-method-key/pull/41#issuecomment-969243244), but the length encoding is more complex than I remembered.

The RSAPublicKey ASN.1 type is a sequence (array) containing two integers. The specification for DER is ITU-T X.690 | ISO/IEC 8825-1. The length encoding is described on page 14 (8.1.3.3 - 8.1.3.5). Each value in the data structure (the sequence, and each of the two integers) is encoded as tag-length-value. The tag for the sequence type is 0x30, and the tag for the integer type is 0x02 (putting aside "constructed" types which I don't think occur here.)

Looking at two example keys from https://github.com/multiformats/multicodec/pull/233#issue-1010247881, the initial bytes are the following for a 2048-bit key: 30 82 01 0a 02 82 01 01 00 and the following for a 4096-bit key: 30 82 02 0a 02 82 02 01 00 Then the modulus follows (2048 or 4096 bits, respectively). Then the exponent follows: 02 03 01 00 01.

Looking at what those byte values mean: 30 - tag for sequence 82 01 0a - length of sequence (266 - i.e. the rest of the data) OR 82 01 0a (522) for the 4096-bit example 02 - tag for integer 82 01 01 - length of integer (257) OR 82 02 01 (513) 00 - leading zero of the integer value (modulus) ... modulus (256 or 512 bytes) 02 - tag for integer 03 - length of integer (3) 01 00 01 - integer value 65537 (public exponent).

Length encoding is 1 byte if the length is <= 127, in which case the length is encoded in that byte ("short mode"). If the length is > 127, one byte with the high bit set encodes the number of following bytes in the lower 7 bits, and then is followed by that many bytes that encode the length ("long mode"). We see the short mode in this example in the length of the public exponent (0x03 = 3), while the long mode is used for the length of the modulus: 0x82 = high bit set, lower bits are 0x02 (2); following 2 bytes are 0x0101 (257) OR 0x0201 (513).

The leading zero for an integer value is supposed to be used if the high bit of the integer value is set, as the high bit otherwise would be interpreted as a sign bit (reference).

I assume this is too much complexity for this specification, but if it is desired to put this into code, I could try to do so.

OR13 commented 2 years ago

Imo, it is too much complexity for the specification, unless we do the same to all the other key representations.... It might be better to just point to a good source for this information from each key representation.

clehner commented 2 years ago

This was done in #45.