Add documentation for the RSA tree.
This commit is contained in:
@@ -3,6 +3,8 @@ use num::bigint::BigUint;
|
|||||||
use rsa::errors::RSAError;
|
use rsa::errors::RSAError;
|
||||||
use simple_asn1::{ASN1Block,ASN1DecodeErr};
|
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 {
|
pub trait RSAMode {
|
||||||
type Barrett;
|
type Barrett;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use simple_asn1::ASN1DecodeErr;
|
use simple_asn1::ASN1DecodeErr;
|
||||||
use rand;
|
use rand;
|
||||||
|
|
||||||
|
/// A bunch of errors that you can get generating, reading, or
|
||||||
|
/// writing RSA keys.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RSAError {
|
pub enum RSAError {
|
||||||
BadMessageSize,
|
BadMessageSize,
|
||||||
|
|||||||
@@ -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 struct RSAKeyPair<R: RSAMode> {
|
||||||
pub public: RSAPublicKey<R>,
|
pub public: RSAPublicKey<R>,
|
||||||
pub private: RSAPrivateKey<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)]
|
#[derive(PartialEq)]
|
||||||
pub enum RSAPair {
|
pub enum RSAPair {
|
||||||
R512(RSAPublicKey<U512>, RSAPrivateKey<U512>),
|
R512(RSAPublicKey<U512>, RSAPrivateKey<U512>),
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ use rsa::errors::RSAError;
|
|||||||
use rsa::oaep::OAEPParams;
|
use rsa::oaep::OAEPParams;
|
||||||
use rsa::signing_hashes::SigningHash;
|
use rsa::signing_hashes::SigningHash;
|
||||||
|
|
||||||
|
/// An RSA private key. Useful for signing messages and decrypting encrypted
|
||||||
|
/// content.
|
||||||
#[derive(Clone,PartialEq)]
|
#[derive(Clone,PartialEq)]
|
||||||
pub struct RSAPrivateKey<R: RSAMode>
|
pub struct RSAPrivateKey<R: RSAMode>
|
||||||
{
|
{
|
||||||
@@ -12,6 +14,7 @@ pub struct RSAPrivateKey<R: RSAMode>
|
|||||||
pub(crate) d: R
|
pub(crate) d: R
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A generic RSA private key which is agnostic to its key size.
|
||||||
#[derive(Clone,PartialEq)]
|
#[derive(Clone,PartialEq)]
|
||||||
pub enum RSAPrivate {
|
pub enum RSAPrivate {
|
||||||
Key512(RSAPrivateKey<U512>),
|
Key512(RSAPrivateKey<U512>),
|
||||||
@@ -27,11 +30,19 @@ macro_rules! generate_rsa_private
|
|||||||
{
|
{
|
||||||
($num: ident, $bar: ident, $size: expr) => {
|
($num: ident, $bar: ident, $size: expr) => {
|
||||||
impl RSAPrivateKey<$num> {
|
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> {
|
pub fn new(n: $num, d: $num) -> RSAPrivateKey<$num> {
|
||||||
let nu = $bar::new(n.clone());
|
let nu = $bar::new(n.clone());
|
||||||
RSAPrivateKey{ nu: nu, d: d }
|
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])
|
pub fn sign(&self, signhash: &SigningHash, msg: &[u8])
|
||||||
-> Vec<u8>
|
-> Vec<u8>
|
||||||
{
|
{
|
||||||
@@ -43,6 +54,13 @@ macro_rules! generate_rsa_private
|
|||||||
sig
|
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])
|
pub fn decrypt<H>(&self, oaep: &OAEPParams<H>, msg: &[u8])
|
||||||
-> Result<Vec<u8>,RSAError>
|
-> Result<Vec<u8>,RSAError>
|
||||||
where H: Default + Digest + FixedOutput
|
where H: Default + Digest + FixedOutput
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr,
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use utils::TranslateNums;
|
use utils::TranslateNums;
|
||||||
|
|
||||||
|
/// An RSA public key. Useful for verifying signatures or encrypting data to
|
||||||
|
/// send to the private key holder.
|
||||||
#[derive(Clone,PartialEq)]
|
#[derive(Clone,PartialEq)]
|
||||||
pub struct RSAPublicKey<R: RSAMode> {
|
pub struct RSAPublicKey<R: RSAMode> {
|
||||||
pub(crate) n: R,
|
pub(crate) n: R,
|
||||||
@@ -19,6 +21,7 @@ pub struct RSAPublicKey<R: RSAMode> {
|
|||||||
pub(crate) e: R
|
pub(crate) e: R
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A generic private key that is agnostic to the key size.
|
||||||
#[derive(Clone,PartialEq)]
|
#[derive(Clone,PartialEq)]
|
||||||
pub enum RSAPublic {
|
pub enum RSAPublic {
|
||||||
Key512( RSAPublicKey<U512>),
|
Key512( RSAPublicKey<U512>),
|
||||||
@@ -31,6 +34,9 @@ pub enum RSAPublic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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
|
pub fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8]) -> bool
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
Reference in New Issue
Block a user