facebook / winterfell

A STARK prover and verifier for arbitrary computations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`f64` field: `BaseElement` should not be convertible from `u64` or `u128` without error

plafer opened this issue · comments

We currently convert From<u64> and From<128> for BaseElement (here). I believe these should be TryFrom<u64> and TryFrom<u128>.

If the value is greater than 2^64 - 2^32 + 1, we silently perform a modulus. This can potentially be a vector of attack. For example, in the Miden VM, BaseElement is sometimes used to represent the length of a list. When initializing the VM, we take the list length as a u64, and then into BaseElement. Basically, if the list is very long (>= 2^64 - 2^32 + 1), there will be a silent wrap, and we will end up processing just a few elements in the VM. Now I don't know of any hardware that can store any list of that kind of size, but I can see this wrapping used in conjunction with other vulnerabilities to create a hack.

This is a direct consequence of the fact that if I store 2^64 - 2^32 + 100 in a u64, I see this as being unrepresentable in a BaseElement, as opposed to thinking of it as equivalent to 100.

In case some users need the current behavior, I would create a function, say from_u64_with_wrapping(), and have the canonical Rust conversion (i.e. From/TryFrom) be "safer".

Would love to hear your thoughts on this. Do you also see it as enabling vulnerabilities of some kind?