Historical software follow-up: fixed public SEC generator precursors
==================================================================

Result
------
No exact generating recipe was found. A new, source-supported PARI model is
excluded for every initial recurrence state under precise packing assumptions.
The separate archived MIRACL default-state check also gives no match within
its stated finite range. Neither result identifies an author, proves a hash
origin, or establishes a security property.

1. New PARI result: exact recurrence-and-packing exclusion
-------------------------------------------------------
Primary source:
https://pari.math.u-bordeaux.fr/pub/pari/OLD/2.0/pari-2.0.16.beta.tgz
The archive's CHANGES states that 2.0.16.beta was released 29/06/99. Its
parigen.h CVS header is dated 1999/06/29. The official archive listing agrees.
Thus this is a period implementation, not a modern RNG attributed backwards.

The random section in src/basemath/bibli2.c is identical in 2.0.16.beta and
2.0.17.beta. src/headers/parigen.h selects the 31-bit recurrence by default,
including on a 64-bit host; it explicitly documents changing the macro to
64 as an optional alternative.

The default state is 1. The recurrences are:
  shipped:  s <- (1000276549*s + 12347) mod 2^31;
  optional: s <- (1000000000000654397*s + 12347) mod 2^63.

The bounded-integer routine differs from bare random(). gp_rand packs:
  32-bit words, shipped recurrence: two pieces of 16 bits at state bits12..27;
  64-bit words, shipped recurrence: four such 16-bit pieces;
  64-bit words, optional recurrence: two pieces of 32 bits at bits12..43.
genrand(N) initially scales limbs against the bound; once a limb is strictly
below the corresponding bound limb, every remaining limb is a raw gp_rand
word. For each tested coordinate the first limb is already strictly below
the corresponding first limb of 2^field_bits. The same is true for the
relevant prime modulus for each prime-field coordinate. Hence the lower128
bits are necessarily consecutive, unmodified gp_rand words under this model.
The replay asserts these bound inequalities, including both p224 and p256.

Exact fixed targets:
  sect131r1 precursor: 0x10134db223421eb623422888a7879682
  sect131r2 precursor: 0x10134db223421eb623422888a7879684
  sect193r1/r2 precursor: 0x23daf8a23206f9c4f299d7b21a9c369137f2c84ae1aa04
  secp160k1 half-G x: 0x48ce563f89a0ed9414f5aa28ad0d96d6795f9c62
  secp192k1 half-G x: 0x554123b78ce563f89a0ed9414f5aa28ad0d96d6795f9c66
  secp224k1/secp256k1 half-G x:
    0x3b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63
Each exact target and its immediate predecessor were checked: six targets
times two values times three models = 36 cases. All36 are incompatible.

Why this is an all-state check rather than a seed list:
If the visible piece is s bits wide, the observed bits and their successors
depend only on state modulo 2^(12+s). Higher state bits cannot propagate
downwards through multiplication and addition modulo a power of two. Once
the first visible piece is specified, exactly4096 low-bit residues remain.
Every one is checked. No recovered states are returned or saved.

C does not specify the evaluation order of the operands in the packing
expression. The check allows every permutation of the pieces separately
inside every output word. It compares the multiset of chronological pieces
with the multiset of observed pieces. This is more permissive than assuming
one fixed compiler order, so order uncertainty cannot rescue these cases.
Calls between observed words must still be consecutive. Interleaved external
calls, arbitrary increments after drawing, different bounds that scale the
observed words, and hashing or other transformations are not excluded.

Controls:
The original mymyrand and gp_rand C functions were compiled with their
historical packing macros. The optional signed-overflow recurrence was built
with -fwrapv. All96 recorded original-function values agree with the portable
model. All43 overlapping128-bit windows from those C outputs survive the
same all-state check, serving as positive tests of the rejection logic.

Independent contemporary control, Bill Allombert, 7 June2000:
http://megrez.math.u-bordeaux1.fr/archives/pari-dev-0006/msg00005.html
  setrand(1);random -> 1000288896
  setrand(1);random(2^31) -> 1559883374
Both controls pass. This message also describes the middle16-bit assembly.

Older PARI1.39 (official release announcement16 January1995) already has the
same recurrence/default, but genrand there has no arbitrary-bound argument.
The bounded-integer exclusion is explicitly about the inspected2.0.16/17
source, not all PARI versions or every possible user-written wrapper.

2. Archived MIRACL: new binary-target replay only
------------------------------------------------
Primary archive:
https://www.mirrorservice.org/sites/ftp.wiretapped.net/pub/security/cryptography/libraries/math/miracl/miracl.zip
Directory listing dates this archive30 April1996. MRCORE.C/MRRAND.C carry
copyright1988-1993 and internal ZIP dates29 July1993/18 February1993.

The archived mirsys calls irand(0L); irand warms up with1000 brand calls.
Archive configurations use32-bit unsigned-long internal state and16- or
32-bit small output. Both source-listed (NK,NJ,NV) triples are included:
(37,24,14) and(21,6,8). At base0, bigrand(w,x) appends low-first words until
raw>=w-2 and returns raw%(w-2)+2. These lower-bound adjustments are important;
they differ from current upstream code.

Only bounds2^131 and2^193 were added here. Each model checks starting output
word offsets0..9999, for80,000 candidates. No exact match to either131
precursor or the common193 precursor. All128 earlier recorded original-C
control words pass. The prior prime-core scan was not repeated.

An archive-wide source search found default irand(0L), user-entered example
seeds, and a time-derived example seed. It did not justify another hardcoded
public example seed. No date or user-seed search was performed. This excludes
only the stated default, configurations, bounds and offsets, not MIRACL
generally. Historical availability of its integer RNG alone would not prove
or disprove use in a separate binary-curve implementation.

3. Other software: source leads, no experimental claim
-----------------------------------------------------
Official Maple documentation identifies the old rand algorithm through
Maple9.5 as the linear congruence x<-427419669081*x mod999999999989 and shows
large-integer assembly in base10^12. No historical default-state control was
established here, so it was not tested or counted as an exclusion:
https://www.maplesoft.com/support/help/maple/view.aspx?path=RandomTools%2FLinearCongruence
https://www.maplesoft.com/support/help/maple/view.aspx?path=RandomTools/LinearCongruence/NewGenerator

The official Magma handbook dates its Monster RNG to version2.7, June2000,
and later MD5 combination to version2.13, July2006. This does not establish
the pre-September1999 generator, so no backward attribution or test was made:
https://magma.maths.usyd.edu.au/magma/handbook/text/18

Portable replay files
---------------------
  python -S check_public_pari.py
  python -S check_public_miracl_binary.py
Required adjacent files: pari-source-controls.json and
miracl-historical-controls.json. Each command writes its corresponding
public-*-results.json. Both use only Python's standard library; no compilation,
network, installed packages or external C source is needed for replay.
Source/archive hashes and chronology are in source-provenance.json.
External source archives and whole C files are research inputs, not needed
in a redistributed replay package.
