-
Notifications
You must be signed in to change notification settings - Fork 56
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
improve documentation with usage examples #283
Comments
What methods do you think would benefit from usage examples? Just a few examples (sorry for the repetition). Or, alternatively, for what usage scenarios it is unclear how to perform them, so that an example is needed? Also if I may criticize your example a little:
|
We've had several requests to improve documentation on this library and I agree it's a general problem. But I'm left feeling like @fjarri that I'm not sure what specific kinds of documentation would be helpful, and I've generally had trouble getting straight answers out of people as to what specific improvements they'd like to see. There are already several toplevel usage examples. Some inline ones would probably make sense, but identifying where would be a first step. |
Thank you so much for this, this is very helpful to me as I learn best practices. Im building out a cryptosystem as an academic project and if you felt inclined I would invite you to give feedback on the rest of the repo :D
I dont know if this is helpful to you both but maybe the perspective I can share is someone who is coming from num-bigint /rug and is unfamiliar with crypto-bigint, specifically for modular multiplication and reduction. Eventually I was able to come up with this: let product_mod_p = montgomery_reduction(&a.mul_wide(&b), &Modulus::MODULUS, Modulus::MOD_NEG_INV); The documentation for this function reads: "Algorithm 14.32 in Handbook of Applied Cryptography https://cacr.uwaterloo.ca/hac/about/chap14.pdf" And thats it, so here are the questions I had to answer on my own, that robust documentation may be able to address:
Ultimately Im looking at a repo like dalek and seeing more text than code almost. I absolutely respect the value of intent revealing code but Im questioning if its safe to assume that someone who wants to take advantage of the benefits of crypto-bigint should be expected to answer the above questions on their own. This is only one example, the rest of the standard operations (+, - etc) were simple enough to figure out. As I work with this library more I can pinpoint additional functions that may present similar questions regarding their usage.
Sorry for the essay, but my answer to this on my own work is usually "anything directly facing the caller should probably have an example of how we expect someone to use our library". Hope this helps and thanks again for taking the time to engage. |
To answer this question:
https://github.com/RustCrypto/crypto-bigint#goals
I'm not sure if that's not clear enough or what. We can explicitly document that every function which doesn't end with |
I only bring it up because some functions do actually explicitly label themselves as constant time in the documentation, such as add_mod for example: "Computes self + rhs mod p in constant time." To a newcomer, this may suggest that a function could be variable time if it is not labelled as such in the documentation. But, I do agree with you that the readme is very clear and should be fine. |
Honestly I wasn't even aware that
I would disagree with that, most methods in
This should be fixed. |
As a newcomer looking for a simple mul mod I dont know how I would ever have found this to be honest, and this is probably due to my own relative inexperience, but it doesnt seem terribly unrealistic to anticipate a 1:1 API with
If you'd like someone to help with this I can open a PR and track down all the places where this is happening. Thanks for the attention to this.
Agreed. Also, if DynResidue/Residue should be the correct way to achieve a modular reduction, showing it in action would be greatly beneficial. The documentation here appears to be substantially more concrete but an example demonstrating how DynResidue/Residue can be used to carry out a modular reduction would be fantastic. |
Open to better names... that one came from quite a bit of bikeshedding.
We can probably re-export the contents of both modules under Perhaps we could remove |
Here is a simple PR that should address the documentation inconsistency. |
Would something like this format be beneficial? /// Computes self / rhs, returns the quotient, remainder.
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, NonZero};
///
/// let a = U448::from(8_u64);
/// let b = NonZero::new(U448::from(4_u64)).unwrap();
/// let res = a.div_rem(&b);
///
/// assert!(res.0 == U448::from(2_u64));
/// assert!(res.1 == U448::ZERO);
/// ```
pub fn div_rem(&self, rhs: &NonZero<Self>) -> (Self, Self) {
// Since `rhs` is nonzero, this should always hold.
let (q, r, _c) = self.ct_div_rem(rhs);
(q, r)
} This example is helpful in this case because it is relatively easy to get started with a Uint, but it is unclear how to get a Nonzero. I needed to search the entire repo for an example in a unit test to find this: let b = NonZero::new(U448::from(4_u64)).unwrap(); If we like this format, I can move through the rest of the repo where this might help, specifically in cases where the operation is happening on a type outside that of |
I would argue that this is one of those methods where a usage example is not necessary. The information on how to create a |
I wont disagree, but its hard for me to get onboard with the idea that following that sequence of steps you just mentioned is easier than simply hovering over the function in an ide and having the correct, safe usage presented to you immediately. Specifically, I struggled here because there is a Im sympathetic to the argument though that if we're sacrificing ease of use to ensure that the user is absolutely sure about what theyre doing by guiding them through the docs in this way youve mentioned and forcing them to find the correct answers to those questions on their own, then maybe that does make more sense over what Im suggesting. I could see it increasing understanding of the library as a whole in some way I guess. |
@drcapybara I think your example could be OK, however it shouldn't use |
heres a preliminary PR extending this pattern to some of the functions in div. could use some review if it makes sense |
I understand that this library is a work in progress, and a substantial amount of effort and work has and continues to go into bringing awesome functionality to life. So this isn't at all a criticism, but the documentation for public-facing apis, particularly in the modular math department, feels lacking. This has made it difficult to get started with the library.
Rust has one of the best documentation systems I've had the pleasure of using so far. If the code for some of the functions in the API is considered stable, and would benefit from documentation, Id like to propose that we begin to add usage examples. This will enhance the library by:
I fully acknowledge that this only makes sense if the functions we want to document are stable. If things are still developing and will dramatically change soon, we should we wait for stability. If it makes sense to do all of this, I volunteer as tribute for this task if no one else feels strongly compelled. Here is a sample of some of my work from my own cryptosystem Ive built as an academic exercise in cryptographic algorithm design:
If there's a good reason not to do this right now, we can close this issue and move on. But I didnt see this in the current issues list and feel it would greatly benefit current and new users of the library. Thanks for your consideration, sorry for the long message.
The text was updated successfully, but these errors were encountered: