Add documentation for the RSA tree.

This commit is contained in:
2019-05-27 20:13:04 -07:00
parent c5850b4d01
commit 4d2e43620a
5 changed files with 41 additions and 0 deletions

View File

@@ -3,6 +3,8 @@ use num::bigint::BigUint;
use rsa::errors::RSAError;
use simple_asn1::{ASN1Block,ASN1DecodeErr};
/// A valid key size for RSA keys, basically, and a (slightly annoying)
/// trait that is used to tie these types to their Barrett value types.
pub trait RSAMode {
type Barrett;
}

View File

@@ -1,6 +1,8 @@
use simple_asn1::ASN1DecodeErr;
use rand;
/// A bunch of errors that you can get generating, reading, or
/// writing RSA keys.
#[derive(Debug)]
pub enum RSAError {
BadMessageSize,

View File

@@ -57,11 +57,24 @@ fn diff<T>(a: &T, b: &T) -> T
}
}
/// An RSA key pair containing keys of the given size; keeping them in the
/// type means you'll never forget which one you have.
///
/// As an aside:
/// * `U512` should only be used for testing
/// * `U1024` should only be used to support old protocols or devices
/// * `U2048` is probably your bare minimum
/// * `U3072` is a very reasonable choice
/// * **`U4096` is what you should use**
/// * `U8192` is starting to get a bit silly (and slow)
/// * `U15360` is for when you're using encryption to heat your house or server room
pub struct RSAKeyPair<R: RSAMode> {
pub public: RSAPublicKey<R>,
pub private: RSAPrivateKey<R>
}
/// A generic RSA key pair that is agnostic about its key size. It's not
/// totally clear why this is useful, at this point.
#[derive(PartialEq)]
pub enum RSAPair {
R512(RSAPublicKey<U512>, RSAPrivateKey<U512>),

View File

@@ -5,6 +5,8 @@ use rsa::errors::RSAError;
use rsa::oaep::OAEPParams;
use rsa::signing_hashes::SigningHash;
/// An RSA private key. Useful for signing messages and decrypting encrypted
/// content.
#[derive(Clone,PartialEq)]
pub struct RSAPrivateKey<R: RSAMode>
{
@@ -12,6 +14,7 @@ pub struct RSAPrivateKey<R: RSAMode>
pub(crate) d: R
}
/// A generic RSA private key which is agnostic to its key size.
#[derive(Clone,PartialEq)]
pub enum RSAPrivate {
Key512(RSAPrivateKey<U512>),
@@ -27,11 +30,19 @@ macro_rules! generate_rsa_private
{
($num: ident, $bar: ident, $size: expr) => {
impl RSAPrivateKey<$num> {
/// Generate a new private key with the given modulus and private
/// number (`d`). This operation actually does a bit of computation
/// under the hood, in order to speed up future ones, so you might
/// want to strongly consider sharing rather than multiple
/// instantiation. But you do you.
pub fn new(n: $num, d: $num) -> RSAPrivateKey<$num> {
let nu = $bar::new(n.clone());
RSAPrivateKey{ nu: nu, d: d }
}
/// Sign the given message with the given SigningHash, returning
/// the signature. This uses a deterministic PKCS1 method for
/// signing messages, so no RNG required.
pub fn sign(&self, signhash: &SigningHash, msg: &[u8])
-> Vec<u8>
{
@@ -43,6 +54,13 @@ macro_rules! generate_rsa_private
sig
}
/// Decrypted the provided encrypted blob using the given
/// parameters. This does standard RSA OAEP decryption, which is
/// rather slow. If you have a choice, you should probably do
/// something clever, like only use this encryption/decryption
/// method to encrypt/decrypt a shared symmetric key, like an
/// AES key. That way, you only do this operation (which is
/// SO SLOW) for a relatively small amount of data.
pub fn decrypt<H>(&self, oaep: &OAEPParams<H>, msg: &[u8])
-> Result<Vec<u8>,RSAError>
where H: Default + Digest + FixedOutput

View File

@@ -12,6 +12,8 @@ use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr,
use std::fmt;
use utils::TranslateNums;
/// An RSA public key. Useful for verifying signatures or encrypting data to
/// send to the private key holder.
#[derive(Clone,PartialEq)]
pub struct RSAPublicKey<R: RSAMode> {
pub(crate) n: R,
@@ -19,6 +21,7 @@ pub struct RSAPublicKey<R: RSAMode> {
pub(crate) e: R
}
/// A generic private key that is agnostic to the key size.
#[derive(Clone,PartialEq)]
pub enum RSAPublic {
Key512( RSAPublicKey<U512>),
@@ -31,6 +34,9 @@ pub enum RSAPublic {
}
impl RSAPublic {
/// Verify that the given signature is for the given message, passing
/// in the same signing arguments used to sign the message in the
/// first place.
pub fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8]) -> bool
{
match self {