-
Notifications
You must be signed in to change notification settings - Fork 4
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
Drop ReceivedMessage and handle sending decoys in handshake #66
Conversation
cfde203
to
31f6e6a
Compare
bb3f073
to
6c4c59c
Compare
6c4c59c
to
1b40672
Compare
protocol/src/lib.rs
Outdated
PacketType::Decoy => Ok(None), | ||
PacketType::Genuine => { | ||
// Drop the header byte. | ||
contents.remove(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is always the first element, each subsequent element will be shifted to the left on the stack. See this. I don't think this is worth the performance hit if we can help it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good catch. Removing front elements is such a pain...lot of tradeoffs here and not sure I have thought of something good yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think VecDeque
has an additional byte of overhead but would allow pop_front
in constant time. Either that or we just give the caller the decoy byte back and let them take a slice [1..]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VecDeque
would definitely help the impl, but then returning that is weird for the caller. I am trying to find some uses of it in the ecosystem and am struggling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few ideas I am kicking around, trying to find the right balance between performance and complexity on the caller. And just to recap, the issue here is the header byte is covered by the auth tag so needs to present in the lower level libs, but is pretty useless for higher level callers.
- Took a look at the
bytes
crate just for some inspiration since I don't think we would want to add a new dependency. But didn't see anything revolutionary. - Use a
VecDeque
instead of aVec
for the performance, but requires returning aVecDeque
(or otherwise cancel out performance gains). I don't think these are used very often, for example can't find a single use in rust-bitcoin. Feels like a strange requirement to place on the caller given the hope is to lower confusion by removing the header byte. - Anything involving
Vec
(e.g.drain
) will at some point require some byte coping, no way around it. Could just leave it for now, but does feel pretty bad.
Does this lead us back to a custom type? Maybe one which owns the underlying vector but supplies a contents
slice to the caller so they don't have to remember what the header byte is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preferably I would like to address the copies now because it will be a significant pain point for large messages like Block
. I agree that the VecDeque
is not a good return value because iterating over a message backwards is meaningless to the caller. I can't exactly envision how the custom type would resolve the problem. You can fork this and try a new patch or just write over this one if you think you can resolve it that way
69069c7
to
981479d
Compare
981479d
to
ed6e361
Compare
utACK ed6e361 |
Did you happen to test a handshake against a regtest instance? |
Self { bytes } | ||
} | ||
|
||
/// Contents of the payload. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to add something like "excluding the ignore bit" for clarity. Not important at the moment though, just before next release
Gave that a shot now. I had to add the |
Drop ReceivedMessage
ReceivedMessage
struct in favor of thePacketType
enum andPayload
struct.ReceivedMessage
isn't quite right #57PacketReader::decrypt_contents
, everything kinda bubbles up from there. That is still the spot where I am not quite sure to do with the header byte (which is currently only used to flag decoy packets). The caller probably doesn't care about the header byte, but it is difficult to ask for memory allocation to include it, but then ignore it. Figure most will use thewith_alloc
version though where we wrap it behind the Payload struct, so keeping it simple here for now.Send Decoy Packets
Extend the
complete_materials
step of the handshake to optionally send decoy packets. This brings the library 100% up to spec, but more importantly for now, allows for an easy nice unit tests which covers both parties tossing garbage and decoys into the handshake.Small Library Tweaks
Debug
derivations on structs which hold secret values, best practice for security.MessageLengthTooSmall
error variant toCiphertextTooSmall
for clarity.NUM_*
prefix in consts which are specifying the number of bytes and not the bytes themselves.Proxy Updates
Documentation
*
instead of-
.