[GH-ISSUE #133] Documentation clarification request #70

Open
opened 2026-10-13 21:03:18 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @asciimoth on GitHub (Apr 29, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-go/issues/133

During clean room reimplementation of AmnesiaWG obfuscation I found a few places where the public docs and current source appear to disagree, plus one historical question about the removed <c> CPS tag.

Could you please clarify which behavior is intended and, ideally, add an authoritative protocol/implementation docs & test vectors?

Mismatches

First

When I1 missing docs say skip entire I2-I5 chain but source still sends any configured I2-I5.

Public docs say:

If the parameter I1 is missing, the entire chain (I2-I5) is skipped

Current source does not implement that rule.
It just iterates over all 5 slots and sends every non-nil one:

So if only I2 or I4 is configured, node will still send it.

Seconf

Docs say:

<rc N> = "Random ASCII alphanumeric characters [A-Za-z0-9]"

Current source uses only 52 letters and receive-side validation also accepts only letters.

So should <rc> be letters-only, or should the implementation include digits to match the docs?

Third

On the same docs page described fixed-size S3 addition:

  • len(init) = 148 + S1
  • len(resp) = 92 + S2
  • len(cookie) = 64 + S3
  • len(data) = payload + S4

But later the cookie section says that cookie reply gets "a random-length padding prefix of 0..S3 bytes".

Current source uses fixed prefix length for cookie reply and receive-side classification also expects exact fixed length 64 + S3:

So the current implementation is clearly fixed-length for S3, not random 0..S3.

Historical tag

I also noticed that early AWG code had a CPS counter tag <c>:

Later, <c> was removed from the README/docs.

I could not find an explanation in code comments, docs, or that commit message.

Originally created by @asciimoth on GitHub (Apr 29, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-go/issues/133 During clean room reimplementation of AmnesiaWG obfuscation I found a few places where the [public docs](https://docs.amnezia.org/documentation/amnezia-wg/) and current source appear to disagree, plus one historical question about the removed `<c>` CPS tag. Could you please clarify which behavior is intended and, ideally, add an authoritative protocol/implementation docs & test vectors? ## Mismatches ### First When `I1` missing docs say skip entire `I2-I5` chain but source still sends any configured `I2-I5`. [Public docs](https://docs.amnezia.org/documentation/amnezia-wg/) say: ``` If the parameter I1 is missing, the entire chain (I2-I5) is skipped ``` Current source does not implement that rule. It just iterates over all 5 slots and sends every non-nil one: - [SendHandshakeInitiation](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/send.go#L131-L136): - [I1..I5 are parsed independently](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/uapi.go#L415-L448) So if only `I2` or `I4` is configured, node will still send it. ### Seconf Docs say: ``` <rc N> = "Random ASCII alphanumeric characters [A-Za-z0-9]" ``` Current source [uses only 52 letters](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/obf_randchars.go#L9-L30) and receive-side validation also [accepts only letters](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/obf_randchars.go#L33-L39). So should `<rc>` be letters-only, or should the implementation include digits to match the docs? ### Third On the same docs page described fixed-size `S3` addition: - `len(init) = 148 + S1` - `len(resp) = 92 + S2` - `len(cookie) = 64 + S3` - `len(data) = payload + S4` But later the cookie section says that cookie reply gets "a random-length padding prefix of 0..S3 bytes". Current source uses [fixed prefix](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/send.go#L246-L250) length for cookie reply and receive-side classification also expects exact [fixed length](https://github.com/amnezia-vpn/amneziawg-go/blob/master/device/receive.go#L590-L599) `64 + S3`: So the current implementation is clearly fixed-length for `S3`, not random `0..S3`. ## Historical <c> tag I also noticed that early AWG code had a CPS counter tag `<c>`: - [parser](https://github.com/amnezia-vpn/amneziawg-go/blob/f6542209f40f3f8f9e3dc9403d331ad2881fd7e3/device/awg/tag_parser.go#L14-L35) - [generator](https://github.com/amnezia-vpn/amneziawg-go/blob/f6542209f40f3f8f9e3dc9403d331ad2881fd7e3/device/awg/tag_generator.go#L187-L206) Later, `<c>` [was removed](https://github.com/amnezia-vpn/amneziawg-go/commit/e7ef4339e718641fc7bc1b0ea41b538108de77cc) from the README/docs. I could not find an explanation in code comments, docs, or that commit message.
Author
Owner

@ygurov commented on GitHub (Apr 29, 2026):

Hi
Thanks for reporting the issue. 1-3 should be addressed on the docs page, I have let our writers know
Regarding the tag - it was removed in process of migrating AWG 1.5 -> AWG 2.0 due to its useless and untrivial implementation

<!-- gh-comment-id:4346498691 --> @ygurov commented on GitHub (Apr 29, 2026): Hi Thanks for reporting the issue. 1-3 should be addressed on the docs page, I have let our writers know Regarding the <c> tag - it was removed in process of migrating AWG 1.5 -> AWG 2.0 due to its useless and untrivial implementation
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amneziawg-go#70
No description provided.