@@ -258,9 +258,11 @@ not been queried before on `RF`, which is exactly the precondition this transfor
258258requires. See [ Function<D, R>] ({% link manual/language-reference/basics.md %}#functiond-r)
259259for details on ` .domain ` .
260260
261- A related transform, ` FreshInputRFToUniform ` , fires when the argument ` v ` to ` H(v) ` is
262- a ` <-uniq ` -sampled variable used solely in that single call: in that case the input is
263- structurally guaranteed to be fresh, and the RF call is replaced by a uniform sample.
261+ A related transform, ` FreshInputRFToUniform ` , fires when the argument to an RF call
262+ contains a ` <-uniq ` -sampled variable used solely in that single call. The argument may
263+ be a bare variable ` H(v) ` , a tuple ` H([v, x, ...]) ` , or a concatenation ` H(v || x) ` ---
264+ in all cases the ` <-uniq ` component ensures the full argument is fresh, and the RF call
265+ is replaced by a uniform sample.
264266
265267``` prooffrog
266268// Before: RF on uniquely-sampled input
@@ -272,6 +274,17 @@ BitString<n> r <-uniq[RF.domain] BitString<n>;
272274BitString<m> z <- BitString<m>;
273275```
274276
277+ This also works with composite arguments:
278+
279+ ``` prooffrog
280+ // Before: RF on tuple with uniquely-sampled component
281+ BitString<n> ss <-uniq[seen] BitString<n>;
282+ BitString<m> z = H([ss, pk]);
283+
284+ // After: independent uniform sample
285+ BitString<m> z <- BitString<m>;
286+ ```
287+
275288Real-proof pointer: [ ` examples/Proofs/PubKeyEnc/HashedElGamal_INDCPA_ROM_MultiChal.proof ` ] ( https://github.com/ProofFrog/examples/blob/main/Proofs/PubKeyEnc/HashedElGamal_INDCPA_ROM_MultiChal.proof ) -- the proof
276289uses ` FreshInputRFToUniform ` (after the DDH hop places a uniform group element ` c ` in
277290the exclusion set) to collapse ` H(c) ` into a fresh uniform bitstring, which then masks
@@ -281,9 +294,11 @@ the message via XOR.
281294** If this is not firing:** The exclusion set must be a game field, not a local variable
282295(a local set is re-initialized on each oracle call, losing the cross-call freshness
283296guarantee). All calls to the RF must use the same exclusion set. If the argument
284- variable appears more than once (including a second call to the same RF with the same
285- variable), the transform is blocked. The ` <-uniq ` sampling must be present; plain ` <- `
286- does not trigger this rule.
297+ variable appears more than once (including inside a tuple or concatenation and elsewhere),
298+ the transform is blocked. The ` <-uniq ` sampling must be present; plain ` <- `
299+ does not trigger this rule. For composite arguments, only top-level tuple elements and
300+ flattened concatenation leaves are checked --- nested sub-expressions like ` H([f(v), x]) `
301+ are not matched.
287302
288303### ` deterministic ` and ` injective ` annotations
289304
0 commit comments