Skip to content
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

monero: only mask user features on new polyseed, not on decode #503

Merged
merged 4 commits into from
Feb 20, 2024

Conversation

j-berman
Copy link
Contributor

@j-berman j-berman commented Jan 3, 2024

  • This commit ensures a polyseed string that has unsupported features correctly errors on decode (without this PR, the test in this PR would trigger a debug assert, and if instead triggered in a non-debug build then Polyseed::from_string could return an incorrect successful response)
  • Also avoids panicking in debug builds when checksum calculation is unexpectedly wrong

Polyseed reference impl for feature masking:

- This commit ensures a polyseed string that has unsupported features correctly errors on decode (rather than panic in debug build or return an incorrect successful response in prod build)
- Also avoids panicking when checksum calculation is unexpectedly wrong

Polyseed reference impl for feature masking:
- polyseed_create: https://github.com/tevador/polyseed/blob/b7c35bb3c6b91e481ecb04fc235eaff69c507fa1/src/polyseed.c#L61
- polyseed_decode: https://github.com/tevador/polyseed/blob/b7c35bb3c6b91e481ecb04fc235eaff69c507fa1/src/polyseed.c#L212
@kayabaNerve
Copy link
Member

Also avoids panicking in debug builds when checksum calculation is unexpectedly wrong

This is a feature, not a bug.

@@ -405,3 +405,12 @@ fn test_polyseed() {
}
}
}

#[test]
fn test_invalid_polyseed() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd clarify how it's invalid.

@@ -179,6 +179,31 @@ fn valid_entropy(entropy: &Zeroizing<[u8; 32]>) -> bool {
res.into()
}

fn from_internal(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to have this outside the Polyseed impl?

Copy link
Contributor Author

@j-berman j-berman Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from_string will first decode the string and yield the already masked features before passing it over to from_internal. The features shouldn't be masked again (the primary bug this PR is fixing).

from expects an unmasked features, which it then masks for the caller. I matched polyseed_create from the polyseed spec for this behavior, which also takes in unmasked features and masks it for the caller. Source: https://github.com/tevador/polyseed/blob/b7c35bb3c6b91e481ecb04fc235eaff69c507fa1/src/polyseed.c#L61 . I figured it would make sense that monero-serai's from would match the polyseed spec for this behavior since it's the only exposed function that a caller can pass features into.

Because of the above 2 distinct call paths, I pulled out the from_internal and had it take in the already masked features.

Sort of similar line of thinking for the birthday btw (from_string yields the encoded birthday so it's unnecessary to decode it, whereas from expects the decoded birthday which needs to be encoded).

if let Ok(res) = res.as_ref() {
debug_assert_eq!(res.checksum, checksum);
if res.checksum != checksum {
// This should never trigger
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this should never trigger, the debug_assert is valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, why should it be a debug assert and not a normal assert? I see no reason the function should return a normal response in a non-debug build if this statement is true. The seed would be invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess debug assert in one line, then return the invalid seed error in the next could make sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it should be impossible, and is accordingly redundant, so it should be optimized out on release.

@kayabaNerve kayabaNerve merged commit 079fddb into serai-dex:develop Feb 20, 2024
11 of 18 checks passed
kayabaNerve added a commit that referenced this pull request Feb 25, 2024
* monero: only mask user features on new polyseed, not on decode

- This commit ensures a polyseed string that has unsupported features correctly errors on decode (rather than panic in debug build or return an incorrect successful response in prod build)
- Also avoids panicking when checksum calculation is unexpectedly wrong

Polyseed reference impl for feature masking:
- polyseed_create: https://github.com/tevador/polyseed/blob/b7c35bb3c6b91e481ecb04fc235eaff69c507fa1/src/polyseed.c#L61
- polyseed_decode: https://github.com/tevador/polyseed/blob/b7c35bb3c6b91e481ecb04fc235eaff69c507fa1/src/polyseed.c#L212

* PR comments

* Make from_internal a member of Polyseed

* Add accidentally removed newline

---------

Co-authored-by: Luke Parker <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants