-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding modulo field prime to scalar.new #94
base: main
Are you sure you want to change the base?
Adding modulo field prime to scalar.new #94
Conversation
Just realized my lock file was added. Sorry about that. Also my formatting is all off. I am just gonna leave as it can be fixed later. |
@logicalmechanism, please note that you can use the blake224 to map into the field (it's the same cost as blake256 onchain), 224 bits are enough entropy. I think it is valuable to have the function fail on input that is not correct. Take for example the plonk protocol, that requires public inputs to be field elements. |
Forcing users to adopt a specific hash function, such as blake224, doesn't seem optimal, especially when a simple modulo operation can address the issue without restricting flexibility. By using blake224, we are discarding 99.999% of possible hash outputs above its maximum value, which seems like a missed opportunity in terms of utilizing the available entropy. Allowing users to choose any hash function and applying a modulo operation to fit within the field prime feels more inclusive and adaptable. Additionally, it enhances security by enabling stronger or more specialized hash functions without requiring fundamental changes to the protocol. Flexibility in cryptographic primitives can future-proof the system while maintaining robustness. It feels more open to allow any hash to be used and it does improve security thus adding the modulo the field prime for large values makes sense here.
blake2b_256 is the cheapest hash on chain btw. If we are going force users to use blake2b_224 then we really need to update this line of text: https://github.com/aiken-lang/stdlib/blob/main/lib/aiken/crypto.ak#L63 because it makes it seem that we can not use it. |
Hi, Just want to reiterate that I am saying two different things. The first one is aimed at helping you solve a technical design issue, the second one is about this PR.
Given point 2, I am against the change of adding a mod reduction to the Scalar interface to make it never fail (which this PR is about). Note that I am not a maintainer of this repo, so this is just my 2 cents. |
While interfaces should ideally enforce certain constraints to prevent misuse, in the context of finite fields, allowing scalar values larger than the field prime isn't problematic because the underlying arithmetic ensures correctness through modulo reduction. In this example below, we select a number larger than the field prime. It works because it is the same as taking that number modulo the field prime then doing the operation. test generator_2() {
builtin.bls12_381_g1_scalar_mul(
64942298445558615972166883114756892612800147825978349404662577504761794852281,
generator,
) == builtin.bls12_381_g1_scalar_mul(
12506423270432425492719142606570926775109595325450711582058918804823213667768,
generator,
)
} Assume we modulo the field prime: test new_2() {
new(
64942298445558615972166883114756892612800147825978349404662577504761794852281,
) == Some(
Scalar(
12506423270432425492719142606570926775109595325450711582058918804823213667768,
),
)
} So its not going to have unintended security breaches, that is just not how the arithmetic over finite fields works. It does not break anything. |
It works because the built-in function must be well-defined over their domain, and there is no dedicated scalar type in plutus. Meaning that the code behind that built-in does it for you. This for safety of the underlying scalar type in blst, otherwise the C FFI calls fail.
This ambiguity is precisely what one would like to prevent. Constraining the user provided scalars is good, as it can prevent in its most basic form replay attacks. For example, say you have some proof of a statement which includes a scalar. If I add the field prime to one of those scalars (as an integer), the proof looks different, but your method of accepting that proof by modulo reducing it to the scalar, would still accept the proof. |
When using the Fiat-Shamir heuristic with the available in crypto hash functions it is possible to get values larger than the field prime of bls12-381. I have two options, truncating the hash at my function level or I add in a modulo the field prime term for values larger than the field prime.
I opt for modulo the field prime.
Example:
The resulting challenge value from the Fiat-Shamir transform will crash at validation, due to an expect erroring because scalar.new is a scaler if and only if it is in range, thus preventing spending when performing my NIZK.
If we just added a modulo field prime for values larger than the field prime then this never happens.
Also about 54% of blake2b_256 hashes will be larger than the field prime so it probably a good idea to account for this.