Skip to content

Conversation

@thehoul
Copy link

@thehoul thehoul commented Dec 17, 2025

Problem

i2OSP converts x > 0 to a byte string of the specified length xLen. To obtain the bytes, the int was converted into a compatible.Int and Bytes() was called on it using a temporary compatiblemod.Mod. The TODO requested to review this modulo used.

Indeed, the modulo is a problem: in the case of x = 256 and xLen=2, the program shoud return the byte array [1,0] but panics. This is because the modulo used is 127 and thus Bytes() panics because the Int (256) is larger than the modulus (127).

The first problem is that any value that fits on more than 1 byte passed as input will cause the program to panic, no matter the value of xLen.

The second problem is that in the context of an bad input (i.e. some x that requires more bytes than xLen), the program will panic (for the same reason) instead of returning an error. This is not an acceptable behaviour since depending on the inputs, the program will sometimes panic and sometimes return an error for the same reason. For backward compatibility, the program should never crash if the inputs are bad but return an error instead.

Fix

The modulus is now the largest value representable on xLen bytes. This ensures that as long as the input value x can fit on xLen bytes, the program will never panic.

This does not entirely fix the problem because, in the case of bad inputs (i.e x not representable on xLen) bytes, the modulo created will be too small and Bytes() will panic. We also need to check if x > mod. We can do this easily since both are uint64 and it automatically implies that x requires more than xLen (since the modulo created is the largest representable value with xLen bytes)

Thus:

  1. The modulo is now (1 << (8 * xLen)) -1
  2. To be able to create this compatiblemod.Mod, const_mod and var_mod now implement a method NewUint() to create a modulus from a uint64
  3. Test for i2OSP has been added to enforce this behaviour

@github-actions
Copy link

🔒 Could not start CI tests due to missing safe PR label. Please contact a DEDIS maintainer.

1 similar comment
@github-actions
Copy link

🔒 Could not start CI tests due to missing safe PR label. Please contact a DEDIS maintainer.

@thehoul thehoul requested review from jbsv and pierluca December 17, 2025 14:40
@thehoul thehoul self-assigned this Dec 17, 2025
var_mod.go and const_mod.go now have a NewUint() method to create a mod from a uint64
Accordingly adapt hashToField, expandMessageXDM and expandMessageXOF
@thehoul thehoul force-pushed the fix-todo-edwards25519 branch from 6b7afe6 to 01e3fba Compare December 18, 2025 12:21
@jbsv
Copy link
Contributor

jbsv commented Dec 23, 2025

I would try to remove the line

branches: [ master, int32-repro ]
completely to avoid running it against the different go version as specified on master.

Copy link
Contributor

@jbsv jbsv left a comment

Choose a reason for hiding this comment

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

LGTM

@thehoul thehoul merged commit 7286df5 into int32-reviewed Jan 5, 2026
15 of 24 checks passed
@thehoul thehoul deleted the fix-todo-edwards25519 branch January 5, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants