Uh oh!
There was an error while loading. Please reload this page.
crypto-common: add SerializableState trait - #1078
Conversation
| } | ||
| /// Core trait for saving internal state of the hash core and restoring it later. | ||
| pub trait HashCoreInternalState { |
There was a problem hiding this comment.
I'd suggest using Rust's built-in conversion traits rather than defining special methods like internal_state and from_internal_state:
| pubtraitHashCoreInternalState{ | |
| pubtraitHashCoreInternalState:TryFrom<Self::InternalState,Error = Error> + Into<Self::InternalState>{ |
tarcieri
commented
Aug 10, 2022
I think the core notion here is a "serializable state" rather than an "internal state" |
| /// Core trait for saving internal state of the hash core and restoring it later. | ||
| pub trait HashCoreInternalState { | ||
| /// Internal state of the hash core. | ||
| type InternalState; |
There was a problem hiding this comment.
It'd be good to have some bounds here to enable generic code:
| typeInternalState; | |
| typeInternalState:TryFrom<&[u8]> + AsRef<[u8]>; |
There was a problem hiding this comment.
If the internal state consists of several objects, is it possible to implement TryFrom<&[u8]> + AsRef<[u8]>: e.g. internal state of SHA-2 hashes consists of the intermediate hash value (array of u32/u64) and the number of consumed blocks (number u64/u128).
There was a problem hiding this comment.
The use case of this API is serialization, and serialization needs to operate in terms of bytestrings.
If you think there's a use case beyond serialization, can you explain how that use case isn't satisfied by simply cloning an existing digest instance?
There was a problem hiding this comment.
Yes, the use case is serialization only.
Should I then create a byte array and serialize the internal state on my own?
E.g. for Sha256VarCore, I need to allocate an array, copy the intermediate hash value ([u32; STATE_LEN]), and the number of consumed blocks (u64).
Or is it better to return an object that consists of the intermediate hash value and the number of consumed blocks, and this object is Serializable (serde)? But this object can not implement AsRef<[u8]> because it consists of a byte array and number.
There was a problem hiding this comment.
It depends if the state can always be fixed-width or not. If it can, we should probably use an associated generic_array::ArrayLength<u8> instead.
I think it's a pretty reasonable assumption that most digests could support a fixed-width serializable state.
There was a problem hiding this comment.
I agree that it's worth to introduce trait which outputs generic array. Something like this:
pubtypeSerializedState<T> = GenericArray<u8, <TasSerializableState>::SerializedStateSize>;pubtraitSerializableState{typeSerializedStateSize:ArrayLength<u8>;fnserialize(&self) -> SerializedState<Self>;fndeserialize(buf:&SerializedState<Self>) -> Self;}Also do not forget to add warning that serialized state may contain sensitive information, e.g. in the hashes case it can contain parts of unprocessed message.
The trait may go to the crypto-common crate since it may be useful for other algorithms as well.
fc5c8f7 to
45e5ef5Comparerpiasetskyi
commented
Aug 19, 2022
Sorry, missed the last comment. I will move the trait to Should |
rpiasetskyi
commented
Aug 19, 2022
The versions of the crates have to be updated: should they be Right now crypto-common is |
newpavlov
left a comment
There was a problem hiding this comment.
Should deserialize method return Result (if the buffer contains invalid values)?
Yes, I forgot to do it in my snippet. I think we can define the error type in crypto-common (i.e. no need to make it generic).
The versions of the crates have to be updated: should they be 0.1.7/0.10.4 or 0.2.0/0.11.0?
The changes are backwards-compatible, so patch releases should be fine.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
rpiasetskyi
commented
Aug 31, 2022
There is a small issue with It is needed for Is there any known Or should it be implemented via What should be the best place to put it In this case? |
tarcieri
commented
Aug 31, 2022
The serialized state needs to be consistent regardless of the target pointer width. You should pick a sensible on-the-wire representation ( |
newpavlov
commented
Aug 31, 2022
I think we can simply transform |
| fn serialize(&self) -> SerializedState<Self> { | ||
| self.inner.serialize() | ||
| } |
There was a problem hiding this comment.
As a sanity check it could be worth to add into serialized state output size (the OutSize type parameter) and return an error during deserialization if it does not match.
| <T::SerializedStateSize as Add<U9>>::Output: Add<T::BlockSize>, | ||
| <<T::SerializedStateSize as Add<U9>>::Output as Add<T::BlockSize>>::Output: ArrayLength<u8>, | ||
| { | ||
| type SerializedStateSize = Sum<Sum<T::SerializedStateSize, U9>, T::BlockSize>; |
There was a problem hiding this comment.
I think you forgot to change U9 to U2.
| Ok(Self { | ||
| core: T::deserialize(serialized_core)?, | ||
| buffer: BlockBuffer::new(&block_buffer[..pos]), |
There was a problem hiding this comment.
Note that if the buffer is "eager" and pos is equal to block size, new will panic. I guess the simplest solution will be to add try_new method to BlockBuffer.
| Ok(Self { | ||
| core: T::deserialize(serialized_core)?, | ||
| buffer: BlockBuffer::new(block_buffer), |
Converted to draft to avoid emails about failed tests. UPD: Did not help :( |
793f9f2 to
bc9dd77Comparerpiasetskyi
commented
Sep 16, 2022
With the introduction of the |
tarcieri
commented
Sep 16, 2022
No, those are type-level properties which are identical regardless of the state. |
rpiasetskyi
commented
Sep 18, 2022
What do you think about 3447449? |
3611c22 to
2ad3d70Comparerpiasetskyi
commented
Sep 26, 2022
Could you please have a look at afc029e ? This is the implementation of The current implementation doesn't support generics for now. Also, |
waynr
commented
Oct 10, 2023
👋 any chance of getting this merged any time in the near future? |
tarcieri
commented
Oct 10, 2023
@waynr it needs a rebase, at the very least |
waynr
commented
Oct 11, 2023
@tarcieri I'm attempting to rebase but running into compile errors that are pretty much totally incomprehensible to me. This repo is like a firehose of generic types and my puny little brain only has capacity for a trickle. |
tarcieri
commented
Oct 11, 2023
I think @rpiasetskyi said he would take a look |
I figured out that the problem had to do with updating the |
waynr
commented
Oct 11, 2023
Just a quick note - it looks like the issue of the local dependency on crypto-common being broken in master branch for the digest crate is fixed in #1358 so this PR might need to wait for that before being rebased. |
rpiasetskyi
commented
Oct 12, 2023
I am doing a rebase (and migration to |
rpiasetskyi
commented
Oct 16, 2023
@tarcieri Sorry, I was expecting it to update the PR but not to merge it :( |
rpiasetskyi
commented
Oct 16, 2023
Reopen. |
tarcieri
commented
Oct 16, 2023
I think you pushed 0 commits which auto-closed the PR? Regardless I can't reopen it... I think you'd need to push some new commits |
This trait is used for saving internal state of the hash core and
restoring it later.
The original issue was discussed here: RustCrypto/hashes#310