-
Notifications
You must be signed in to change notification settings - Fork 229
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
verify_prehashed seems unnecessarily strict #190
Comments
The reasons are likely the same as the ones given in the "Notes" section of the https://docs.rs/signature/latest/signature/trait.DigestVerifier.html#notes Operating on a raw digest output, rather than an instance of a An attacker who is able to pick that value arbitrarily can compute a valid "signature" with the public key alone by solving a system of linear equations. |
While I can see the benefit of encapsulating the digest to minimize programmer error, I am not sure it follows that carrying around an entire state machine for every digest once computed is very smart from a memory standpoint. Note that this is not behavior enforced by the Digest trait, but by the Sha512 implementation. The digest has an Engine512, which has a long long length, a 64 byte state, and then a block buffer with another usize and its own buffer, all owned by said "digest". Aka its the verb digest not the noun digest. All this means it also serializes poorly which is a pain for edge situations like wasm where multithreading involves marshaling data between webworkers through serialization. I think a solid compromise would be to have an opaque middle digest struct of the "noun" variety, whos construction is limited to a From/Copy/Clone implementation, immutable on the outside yet tender on the inside, which can be consumed by the api where pre-hashed values are needed. This way you can be reasonably sure that it came from the hash function, yet your not passing around all of mcdonalds when you just need the hamburger. I forked the repo and make said trivial changes to support my use case (basically unsafe copies of the ph functions which take a slice), but it would be REALLY nice if at least some "unsafe" functions were exposed which would prevent the need to deviate. |
You can always work around it by defining your own newtype around |
Touche! I could make it fit that way, In fact I am already using a newtype around that already, just not implementing the interface. However one downside with that approach is that it would necessitate doing a lot of unimplemented branches, which sucks for coverage AND puts me at the mercy that dalek does not suddenly decide to take the contract for my faux implementation at face. That scares me. |
I see why it's a pain, but I think supporting anything else would be too prone to user error. We couldn't support just fixed-size arrays, because different digests have different sizes, so it'd have to accept arbitrary I think the above workaround is probably sufficient for motivated end-users with high-performance requirements. Regarding the use of |
FWIW, that's what we ended up going with in the https://docs.rs/signature/latest/signature/hazmat/trait.PrehashSigner.html That said, I haven't proposed or tried implementing the |
Hmm I didn't realize the trait was already there. Due to the nature of the prehashed signing, it'd actually be possible to have a method like Your call if we want something like that tho. |
Sounds like a great idea |
I like the |
The function verify_prehashed (ed25519ph impl) requires the prehashed_message to be a full blown Digest implementation, however its only usage within the function is prehashed_message.finalize().as_slice(). In my use case this is highly inconvenient as I ALREADY have a digest in the form [u8; 64] (which I can convert to the GenericArray equiv). As far as I can see there is no way to initialize a Digest with already existing bytes, really hindering the usage for performance scenarios.
Unless I am missing something, I would propose replacing or adding an implementation that takes either a slice, an array, or a GenericArray (which you would get from finalize) as the prehashed_message argument to the function. Alternatively, if there is a way to construct a Digest from raw bytes this could circumvent the issue, but I have not found a way to coerce this behavior.
The text was updated successfully, but these errors were encountered: