Skip to content

Various corrections to ANS1/DER doc - #2330

Open
bdaehlie wants to merge 1 commit into
mainfrom
asn1-der-corrections
Open

Various corrections to ANS1/DER doc#2330
bdaehlie wants to merge 1 commit into
mainfrom
asn1-der-corrections

Conversation

@bdaehlie

@bdaehlie bdaehlie commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@bdaehlie
bdaehlie requested review from aarongable and jsha September 4, 2026 14:33
Comment on lines -121 to -122
represent in DER is 256<sup>(2\*\*1008)</sup>-1. For a truly unbounded INTEGER you'd
have to encode in BER, which allows indefinitely-long fields.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why delete the unbounded INTEGER comment?

These tags all happen to be under 31 (0x1F), and that's for a good reason: Bits
8, 7, and 6 (the high bits of the tag byte) are used to encode extra
information, so any universal tag numbers higher than 31 would need to
information, so any universal tag numbers of 31 or higher would need to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right? It seems to me that universal tag number 31 would be encoded as 0b00011111, which doesn't interfere with the high bits mentioned above.

Comment on lines +561 to 568
(The IMPLICIT keyword is explained under [EXPLICIT vs IMPLICIT](#explicit-vs-implicit)
below. It matters here: without it the default is EXPLICIT, which produces a
different, longer encoding.)

So now, to encode a Point with just an x coordinate of 9, instead of
encoding x as a UNIVERSAL INTEGER, you'd set bits 8 and 7 of the encoded
tag to (1, 0) to indicate the context specific class, and set the low
bits to 0, giving this encoding:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good catch but pedagogically, we first introduced INTEGER, then INTEGER OPTIONAL, and now [APPLICATION 0] INTEGER OPTIONAL. I'd rather not introduce [APPLICATION 0] and IMPLICIT at the same time in the examples, since it muddies the waters.

Instead, I suggest:

Suggested change
So now, to encode a Point with just an x coordinate of 9, instead of
encoding x as a UNIVERSAL INTEGER, you'd set bits 8 and 7 of the encoded
tag to (1, 0) to indicate the context specific class, and set the low
bits to 0, giving this encoding (assuming [IMPLICIT TAGS](#explicit-vs-implicit)):

Along with reverting the above diffs to the ASN.1 notation.

Comment on lines +1007 to +1008
in ascending order by the tag of each element (first by class, then by tag
number).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh this is a good catch, and subtle. SET and SET OF differ here. For SET, X.690 says:

10.3 Set components
The encodings of the component values of a set value shall appear in an order determined by their tags as specified in 8.6 of
Rec. ITU-T X.680 | ISO/IEC 8824-1.

X.680 says:

8.6 The canonical order for tags is based on the outermost tag of each type and is defined as follows:
a) those elements or alternatives with universal class tags shall appear first, followed by those with
application class tags, followed by those with context-specific tags, followed by those with private class
tags;
b) within each class of tags, the elements or alternatives shall appear in ascending order of their tag
numbers.

This reveals a misunderstanding I've had: I treat the first byte in an encoding as a "tag byte" but X.690 actually calls the first bytes "identifier octets." And a "tag" consists of a (class, tag number) pair (but not the constructed bit, which is an encoding instruction).

I think this deserves a little expansion here to clarify. How about:

In DER, the components of a SET must be encoded in ASN.1's canonical order by their tags. That means ordering first by class (universal, application, context-specific, private in that order), then by tag number. This differs from simply sorting encoded elements because it ignores the constructed bit, and also ignores the encoding nuances of high tag numbers.

Also we need some tweaks below since the definition of SET OF refers to this.

Comment on lines 1013 to 1018
A SET OF items is encoded the same way as a SET, including the tag byte
of 0x31. For DER encoding, there is a similar requirement that the SET OF
must be encoded in ascending order. Because all elements in the SET OF
have the same type, ordering by tag is not sufficient. So the elements
of a SET OF are sorted by their encoded values, with shorter values
treated as if they were padded to the right with zeroes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A SET OF items is encoded the same way as a SET, including the tag byte
of 0x31. For DER encoding, there is a similar requirement that the SET OF
must be encoded in ascending order. Because all elements in the SET OF
have the same type, ordering by (class, tag number) is not sufficient.
So the elements of a SET OF are sorted by their _encoded values_, with
shorter values treated as if they were padded to the right with zeroes.

@bdaehlie

bdaehlie commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Since you are much more of an expert on this than me, do you want to take over this PR/branch @jsha ?

@jsha

jsha commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Will do, thanks for spotting these issues!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants