Tracking ticket for a known, intentionally deferred assumption -- not a bug to
fix now.
The RFC 4226 counter is built by writing the Int64 in native memory order and
then reversing the bytes:
// Source/radRTL.ByteArrayUtils.pas:29-33
function ConvertToByteArray(const pValue:Int64):TBytes;
begin
SetLength(Result, SizeOf(Int64));
PInt64(@Result[0])^ := pValue; // native order == little-endian on current targets
end;
// Source/radRTL.HOTP.pas:72
vData := ReverseByteArray(ConvertToByteArray(pCounterValue)); // reversed to big-endian
This produces correct big-endian output only because every current Delphi target
is little-endian (Win32/Win64/Linux x64/macOS/iOS/Android are all LE). On a
hypothetical big-endian target the reverse step would flip already-correct bytes
and produce a wrong counter. The dependency is implicit -- nothing in the code
fails or warns on a BE host.
Decision: deferred. Changing working, RFC-vector-verified logic to guard
against a platform that does not exist for Delphi is not worth the churn. This
ticket exists so the assumption is findable if that ever changes, rather than
living only as a buried code comment. The author's blog article
(radprogrammer.com) also details why the reversal step is done this way.
Trigger to revisit: Embarcadero ships (or the project adopts) a big-endian
Delphi target, or this code is ported to a toolchain/runtime where big-endian is
possible.
Reference fix when/if triggered (host-independent, also removes ReverseByteArray
from the OTP path):
function ConvertToBigEndianBytes(const pValue:Int64):TBytes;
var
i:Integer;
begin
SetLength(Result, SizeOf(Int64));
for i := 0 to 7 do
Result[i] := Byte(UInt64(pValue) shr (56 - i * 8)); // Result[0]=MSB .. Result[7]=LSB
end;
Shifts act on the value, not the memory layout, so the output is identical on LE
and BE hosts. RFC 4226/6238 vector tests are the safety net for any future swap.
Acceptance criteria (only if the trigger occurs):
Tracking ticket for a known, intentionally deferred assumption -- not a bug to
fix now.
The RFC 4226 counter is built by writing the
Int64in native memory order andthen reversing the bytes:
This produces correct big-endian output only because every current Delphi target
is little-endian (Win32/Win64/Linux x64/macOS/iOS/Android are all LE). On a
hypothetical big-endian target the reverse step would flip already-correct bytes
and produce a wrong counter. The dependency is implicit -- nothing in the code
fails or warns on a BE host.
Decision: deferred. Changing working, RFC-vector-verified logic to guard
against a platform that does not exist for Delphi is not worth the churn. This
ticket exists so the assumption is findable if that ever changes, rather than
living only as a buried code comment. The author's blog article
(radprogrammer.com) also details why the reversal step is done this way.
Trigger to revisit: Embarcadero ships (or the project adopts) a big-endian
Delphi target, or this code is ported to a toolchain/runtime where big-endian is
possible.
Reference fix when/if triggered (host-independent, also removes
ReverseByteArrayfrom the OTP path):
Shifts act on the value, not the memory layout, so the output is identical on LE
and BE hosts. RFC 4226/6238 vector tests are the safety net for any future swap.
Acceptance criteria (only if the trigger occurs):
ReverseByteArrayis removed from the OTP path (or retained only if still used elsewhere).