Starting to include RSA crypto.
This commit is contained in:
@@ -9,8 +9,11 @@ license-file = "LICENSE"
|
||||
repository = "https://github.com/acw/simple_crypto"
|
||||
|
||||
[dependencies]
|
||||
digest = "^0.7.1"
|
||||
num = "^0.1.42"
|
||||
rand = "^0.3"
|
||||
sha-1 = "^0.7.0"
|
||||
sha2 = "^0.7.0"
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "^0.4.1"
|
||||
|
||||
@@ -9,5 +9,5 @@ mod unsigned;
|
||||
mod gold_tests;
|
||||
|
||||
pub use self::signed::SCN;
|
||||
pub use self::unsigned::UCN;
|
||||
pub use self::unsigned::{BarrettUCN,UCN};
|
||||
pub use self::primes::*;
|
||||
|
||||
@@ -53,24 +53,26 @@ impl UCN {
|
||||
let candidate = base | &one;
|
||||
|
||||
if let Some(proposed) = check_value(candidate) {
|
||||
if proposed.probably_prime(rng, iterations) {
|
||||
if proposed.probably_prime(rng, bitlen, iterations) {
|
||||
return proposed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn probably_prime<G: Rng>(&self, g: &mut G, iters: usize) -> bool {
|
||||
fn probably_prime<G: Rng>(&self, g: &mut G, size: usize, iters: usize)
|
||||
-> bool
|
||||
{
|
||||
for tester in SMALL_PRIMES.iter() {
|
||||
if (self % UCN::from(*tester)).is_zero() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
miller_rabin(g, &self, iters)
|
||||
miller_rabin(g, &self, size, iters)
|
||||
}
|
||||
}
|
||||
|
||||
fn miller_rabin<G: Rng>(g: &mut G, n: &UCN, iters: usize) -> bool {
|
||||
fn miller_rabin<G: Rng>(g: &mut G, n: &UCN, size: usize, iters: usize) -> bool {
|
||||
let one = UCN::from(1 as u8);
|
||||
let two = UCN::from(2 as u8);
|
||||
let nm1 = n - &one;
|
||||
@@ -86,7 +88,7 @@ fn miller_rabin<G: Rng>(g: &mut G, n: &UCN, iters: usize) -> bool {
|
||||
// WitnessLoop: repeat k times
|
||||
'WitnessLoop: for _k in 0..iters {
|
||||
// pick a random integer a in the range [2, n - 2]
|
||||
let a = random_in_range(g, &two, &nm1);
|
||||
let a = random_in_range(g, size, &two, &nm1);
|
||||
// x <- a^d mod n
|
||||
let mut x = a.modexp(&d, &n);
|
||||
// if x = 1 or x = n - 1 then
|
||||
@@ -116,8 +118,9 @@ fn miller_rabin<G: Rng>(g: &mut G, n: &UCN, iters: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn random_in_range<G: Rng>(rng: &mut G, min: &UCN, max: &UCN) -> UCN {
|
||||
let bitlen = ((max.bits() + 63) / 64) * 64;
|
||||
fn random_in_range<G: Rng>(rng: &mut G, bitlen: usize, min: &UCN, max: &UCN)
|
||||
-> UCN
|
||||
{
|
||||
loop {
|
||||
let candidate = random_number(rng, bitlen);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ pub struct UCN {
|
||||
pub(crate) contents: Vec<u64>
|
||||
}
|
||||
|
||||
#[derive(Clone,Debug,PartialEq,Eq)]
|
||||
pub struct BarrettUCN {
|
||||
pub(crate) u: UCN,
|
||||
pub(crate) k: usize,
|
||||
@@ -185,7 +186,6 @@ impl UCN {
|
||||
let mylen = self.contents.len() * 8;
|
||||
let mut res = Vec::with_capacity(len);
|
||||
|
||||
println!("mylen: {} len: {}", mylen, len);
|
||||
assert!( (len % 8) == 0 );
|
||||
assert!( mylen <= len );
|
||||
for _ in 0..(len - mylen) {
|
||||
|
||||
@@ -10,15 +10,22 @@
|
||||
//! when they should use it, and examples. For now, it mostly just fowards
|
||||
//! off to more detailed modules. Help requested!
|
||||
|
||||
extern crate digest;
|
||||
extern crate num;
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate quickcheck;
|
||||
extern crate rand;
|
||||
extern crate sha1;
|
||||
extern crate sha2;
|
||||
|
||||
/// The cryptonum module provides support for large numbers for use in various
|
||||
/// cryptographically-relevant algorithms.
|
||||
pub mod cryptonum;
|
||||
/// The rsa module provides support for RSA-related core algorithms, including
|
||||
/// signing / verification and encryption / decryption. You can also generate
|
||||
/// key material there.
|
||||
pub mod rsa;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
159
src/rsa/core.rs
Normal file
159
src/rsa/core.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use cryptonum::{BarrettUCN,UCN};
|
||||
use rand::Rng;
|
||||
|
||||
pub static ACCEPTABLE_KEY_SIZES: [(usize,usize); 8] =
|
||||
[(512, 7),
|
||||
(1024, 7),
|
||||
(2048, 4),
|
||||
(3072, 3),
|
||||
(4096, 3),
|
||||
(7680, 3),
|
||||
(8192, 3),
|
||||
(15360, 3)];
|
||||
|
||||
fn iterations_for_size(l: usize) -> usize {
|
||||
for &(m, i) in ACCEPTABLE_KEY_SIZES.iter() {
|
||||
if m == l {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
panic!("Bad key size, can't get M-R iterations")
|
||||
}
|
||||
|
||||
pub fn generate_pq<G: Rng>(rng: &mut G, e: &UCN, bitlen: usize) -> (UCN, UCN) {
|
||||
let iterations = iterations_for_size(bitlen);
|
||||
let sqrt2 = UCN::from(6074001000 as u64);
|
||||
let topbit = UCN::from(1 as u64) << ((bitlen / 2) - 1);
|
||||
let minval = sqrt2 << ((bitlen / 2) - 33);
|
||||
let mindiff = UCN::from(1 as u64) << ((bitlen / 2) - 101);
|
||||
let validate = |inval| {
|
||||
let x = &inval | &topbit;
|
||||
if x < minval {
|
||||
return None
|
||||
}
|
||||
if !gcd_is_one(&e, &x) {
|
||||
return None
|
||||
}
|
||||
Some(x)
|
||||
};
|
||||
|
||||
let p = UCN::generate_prime(rng, bitlen / 2, iterations, validate);
|
||||
loop {
|
||||
let q = UCN::generate_prime(rng, bitlen / 2, iterations, validate);
|
||||
|
||||
if diff(&p, &q) >= mindiff {
|
||||
return (p, q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn diff(a: &UCN, b: &UCN) -> UCN {
|
||||
if a > b {
|
||||
a - b
|
||||
} else {
|
||||
b - a
|
||||
}
|
||||
}
|
||||
|
||||
fn gcd_is_one(a: &UCN, b: &UCN) -> bool {
|
||||
let mut u = a.clone();
|
||||
let mut v = b.clone();
|
||||
|
||||
if u.is_zero() {
|
||||
return v == UCN::from(1 as u8);
|
||||
}
|
||||
|
||||
if v.is_zero() {
|
||||
return u == UCN::from(1 as u8);
|
||||
}
|
||||
|
||||
if u.is_even() && v.is_even() {
|
||||
return false;
|
||||
}
|
||||
|
||||
while u.is_even() {
|
||||
u >>= 1;
|
||||
}
|
||||
|
||||
loop {
|
||||
while v.is_even() {
|
||||
v >>= 1;
|
||||
}
|
||||
// u and v guaranteed to be odd right now.
|
||||
if u > v {
|
||||
// make sure that v > u, so that our subtraction works
|
||||
// out.
|
||||
let t = u;
|
||||
u = v;
|
||||
v = t;
|
||||
}
|
||||
v = v - &u;
|
||||
|
||||
if v.is_zero() {
|
||||
return u == UCN::from(1 as u64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// the RSA encryption function
|
||||
pub fn ep(nu: &BarrettUCN, e: &UCN, m: &UCN) -> UCN {
|
||||
m.fastmodexp(e, nu)
|
||||
}
|
||||
|
||||
// the RSA decryption function
|
||||
pub fn dp(nu: &BarrettUCN, d: &UCN, c: &UCN) -> UCN {
|
||||
c.fastmodexp(d, nu)
|
||||
}
|
||||
|
||||
// the RSA signature generation function
|
||||
pub fn sp1(nu: &BarrettUCN, d: &UCN, m: &UCN) -> UCN {
|
||||
m.fastmodexp(d, nu)
|
||||
}
|
||||
|
||||
// the RSA signature verification function
|
||||
pub fn vp1(nu: &BarrettUCN, e: &UCN, s: &UCN) -> UCN {
|
||||
s.fastmodexp(e, nu)
|
||||
}
|
||||
|
||||
// encoding PKCS1 stuff
|
||||
pub fn pkcs1_pad(ident: &[u8], hash: &[u8], keylen: usize) -> Vec<u8> {
|
||||
let mut idhash = Vec::new();
|
||||
idhash.extend_from_slice(ident);
|
||||
idhash.extend_from_slice(hash);
|
||||
let tlen = idhash.len();
|
||||
assert!(keylen > (tlen + 3));
|
||||
let mut padding = Vec::new();
|
||||
padding.resize(keylen - tlen - 3, 0xFF);
|
||||
let mut result = vec![0x00, 0x01];
|
||||
result.append(&mut padding);
|
||||
result.push(0x00);
|
||||
result.append(&mut idhash);
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand::OsRng;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn can_get_p_and_q() {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let e = UCN::from(65537 as u64);
|
||||
|
||||
for &(size, _) in ACCEPTABLE_KEY_SIZES.iter().take(3) {
|
||||
let (p,q) = generate_pq(&mut rng, &e, size);
|
||||
let minval = UCN::from(1 as u8) << ((size / 2) - 1);
|
||||
assert!(p > minval);
|
||||
assert!(q > minval);
|
||||
assert!(p != q);
|
||||
assert!(p.is_odd());
|
||||
assert!(q.is_odd());
|
||||
let phi = (p - UCN::from(1 as u64)) * (q - UCN::from(1 as u64));
|
||||
let d = e.modinv(&phi);
|
||||
assert_eq!( (&e * &d) % phi, UCN::from(1 as u64) );
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/rsa/errors.rs
Normal file
14
src/rsa/errors.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RSAKeyGenError {
|
||||
InvalidKeySize(usize), RngFailure(io::Error)
|
||||
}
|
||||
|
||||
impl From<io::Error> for RSAKeyGenError {
|
||||
fn from(e: io::Error) -> RSAKeyGenError {
|
||||
RSAKeyGenError::RngFailure(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
104
src/rsa/mod.rs
Normal file
104
src/rsa/mod.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
mod core;
|
||||
mod errors;
|
||||
mod public;
|
||||
mod private;
|
||||
mod signing_hashes;
|
||||
|
||||
pub use self::public::RSAPublic;
|
||||
pub use self::private::RSAPrivate;
|
||||
pub use self::signing_hashes::{SigningHash,
|
||||
SIGNING_HASH_NULL, SIGNING_HASH_SHA1,
|
||||
SIGNING_HASH_SHA224, SIGNING_HASH_SHA256,
|
||||
SIGNING_HASH_SHA384, SIGNING_HASH_SHA512};
|
||||
|
||||
use cryptonum::UCN;
|
||||
use rand::{OsRng,Rng};
|
||||
use self::core::{ACCEPTABLE_KEY_SIZES,generate_pq};
|
||||
use self::errors::*;
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
pub struct RSAKeyPair {
|
||||
pub public: RSAPublic,
|
||||
pub private: RSAPrivate
|
||||
}
|
||||
|
||||
impl RSAKeyPair {
|
||||
/// Generates a fresh RSA key pair of the given bit size. Valid bit sizes
|
||||
/// are 512, 1024, 2048, 3072, 4096, 7680, 8192, and 15360. If you
|
||||
/// actually want to protect data, use a value greater than or equal to
|
||||
/// 2048. If you don't want to spend all day waiting for RSA computations
|
||||
/// to finish, choose a value less than or equal to 4096.
|
||||
///
|
||||
/// This routine will use `OsRng` for entropy. If you want to use your
|
||||
/// own random number generator, use `generate_w_rng`.
|
||||
pub fn generate(len_bits: usize) -> Result<RSAKeyPair,RSAKeyGenError> {
|
||||
let mut rng = OsRng::new()?;
|
||||
RSAKeyPair::generate_w_rng(&mut rng, len_bits)
|
||||
}
|
||||
|
||||
/// Generates a fresh RSA key pair of the given bit size. Valid bit sizes
|
||||
/// are 512, 1024, 2048, 3072, 4096, 7680, 8192, and 15360. If you
|
||||
/// actually want to protect data, use a value greater than or equal to
|
||||
/// 2048. If you don't want to spend all day waiting for RSA computations
|
||||
/// to finish, choose a value less than or equal to 4096.
|
||||
///
|
||||
/// If you provide your own random number generator that is not `OsRng`,
|
||||
/// you should know what you're doing, and be using a cryptographically-
|
||||
/// strong RNG of your own choosing. We've warned you. Use a good one.
|
||||
/// So now it's on you.
|
||||
pub fn generate_w_rng<G: Rng>(rng: &mut G, len_bits: usize)
|
||||
-> Result<RSAKeyPair,RSAKeyGenError>
|
||||
{
|
||||
let e = UCN::from(65537 as u32);
|
||||
|
||||
for &(length, _) in ACCEPTABLE_KEY_SIZES.iter() {
|
||||
if length == len_bits {
|
||||
let (p, q) = generate_pq(rng, &e, len_bits);
|
||||
let n = &p * &q;
|
||||
let one = UCN::from(1 as u8);
|
||||
let phi = (p - &one) * (q - &one);
|
||||
let d = e.modinv(&phi);
|
||||
let public_key = RSAPublic::new(n.clone(), e);
|
||||
let private_key = RSAPrivate::new(n, d);
|
||||
return Ok(RSAKeyPair{
|
||||
private: private_key,
|
||||
public: public_key
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Err(RSAKeyGenError::InvalidKeySize(len_bits))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use quickcheck::{Arbitrary,Gen};
|
||||
use rsa::core::{ep,dp,sp1,vp1};
|
||||
use super::*;
|
||||
|
||||
const TEST_KEY_SIZES: [usize; 2] = [512, 1024];
|
||||
|
||||
impl Arbitrary for RSAKeyPair {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> RSAKeyPair {
|
||||
let size = g.choose(&TEST_KEY_SIZES).unwrap();
|
||||
RSAKeyPair::generate_w_rng(g, *size).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
quickcheck! {
|
||||
fn rsa_ep_dp_inversion(kp: RSAKeyPair, n: UCN) -> bool {
|
||||
let m = n.reduce(&kp.public.nu);
|
||||
let ciphertext = ep(&kp.public.nu, &kp.public.e, &m);
|
||||
let mprime = dp(&kp.private.nu, &kp.private.d, &ciphertext);
|
||||
mprime == m
|
||||
}
|
||||
fn rsa_sp_vp_inversion(kp: RSAKeyPair, n: UCN) -> bool {
|
||||
let m = n.reduce(&kp.public.nu);
|
||||
let sig = sp1(&kp.private.nu, &kp.private.d, &m);
|
||||
let mprime = vp1(&kp.public.nu, &kp.public.e, &sig);
|
||||
mprime == m
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/rsa/private.rs
Normal file
64
src/rsa/private.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use cryptonum::{BarrettUCN,UCN};
|
||||
use rsa::core::{ACCEPTABLE_KEY_SIZES,pkcs1_pad,sp1};
|
||||
use rsa::signing_hashes::SigningHash;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RSAPrivate {
|
||||
pub(crate) byte_len: usize,
|
||||
pub(crate) n: UCN,
|
||||
pub(crate) nu: BarrettUCN,
|
||||
pub(crate) d: UCN
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl fmt::Debug for RSAPrivate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("RSAPrivate")
|
||||
.field("byte_len", &self.byte_len)
|
||||
.field("n", &self.n)
|
||||
.field("nu", &self.nu)
|
||||
.field("d", &self.d)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl PartialEq for RSAPrivate {
|
||||
fn eq(&self, rhs: &RSAPrivate) -> bool {
|
||||
(self.byte_len == rhs.byte_len) &&
|
||||
(self.n == rhs.n) &&
|
||||
(self.nu == rhs.nu) &&
|
||||
(self.d == rhs.d)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl Eq for RSAPrivate {}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl fmt::Debug for RSAPrivate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("RSAPrivateKey<PRIVATE>")
|
||||
}
|
||||
}
|
||||
|
||||
impl RSAPrivate {
|
||||
/// Create a new RSA public key from the given components, which you found
|
||||
/// via some other mechanism.
|
||||
pub fn new(n: UCN, d: UCN) -> RSAPrivate {
|
||||
let len = n.bits();
|
||||
|
||||
for &(valid_bits, _) in ACCEPTABLE_KEY_SIZES.iter() {
|
||||
if valid_bits > len {
|
||||
return RSAPrivate {
|
||||
byte_len: valid_bits / 8,
|
||||
n: n.clone(),
|
||||
nu: n.barrett_u(),
|
||||
d: d.clone()
|
||||
};
|
||||
}
|
||||
}
|
||||
panic!("Invalid RSA key size in new()")
|
||||
}
|
||||
}
|
||||
30
src/rsa/public.rs
Normal file
30
src/rsa/public.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use cryptonum::{BarrettUCN,UCN};
|
||||
use rsa::core::ACCEPTABLE_KEY_SIZES;
|
||||
|
||||
#[derive(Clone,Debug,PartialEq,Eq)]
|
||||
pub struct RSAPublic {
|
||||
pub(crate) byte_len: usize,
|
||||
pub(crate) n: UCN,
|
||||
pub(crate) nu: BarrettUCN,
|
||||
pub(crate) e: UCN
|
||||
}
|
||||
|
||||
impl RSAPublic {
|
||||
/// Create a new RSA public key from the given components, which you found
|
||||
/// via some other mechanism.
|
||||
pub fn new(n: UCN, e: UCN) -> RSAPublic {
|
||||
let len = n.bits();
|
||||
|
||||
for &(valid_bits, _) in ACCEPTABLE_KEY_SIZES.iter() {
|
||||
if valid_bits > len {
|
||||
return RSAPublic{
|
||||
byte_len: valid_bits / 8,
|
||||
n: n.clone(),
|
||||
nu: n.barrett_u(),
|
||||
e: e.clone()
|
||||
};
|
||||
}
|
||||
}
|
||||
panic!("Invalid RSA key size in new()")
|
||||
}
|
||||
}
|
||||
119
src/rsa/signing_hashes.rs
Normal file
119
src/rsa/signing_hashes.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use digest::{FixedOutput,Input};
|
||||
use sha1::Sha1;
|
||||
use sha2::{Sha224,Sha256,Sha384,Sha512};
|
||||
use std::fmt;
|
||||
|
||||
/// A hash that can be used to sign a message.
|
||||
#[derive(Clone)]
|
||||
pub struct SigningHash {
|
||||
/// The name of this hash (only used for display purposes)
|
||||
pub name: &'static str,
|
||||
/// The approved identity string for the hash.
|
||||
pub ident: &'static [u8],
|
||||
/// The hash
|
||||
pub run: fn(&[u8]) -> Vec<u8>
|
||||
}
|
||||
|
||||
impl fmt::Debug for SigningHash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
/// The "null" signing hash. This signing hash has no identity, and will
|
||||
/// simply pass the data through unhashed. You really should know what
|
||||
/// you're doing if you use this, and probably using a somewhat strange
|
||||
/// signing protocol. There's no good reason to use this in new code
|
||||
/// for a new protocol or system.
|
||||
pub static SIGNING_HASH_NULL: SigningHash = SigningHash {
|
||||
name: "NULL",
|
||||
ident: &[],
|
||||
run: nohash
|
||||
};
|
||||
|
||||
fn nohash(i: &[u8]) -> Vec<u8> {
|
||||
i.to_vec()
|
||||
}
|
||||
|
||||
/// Sign a hash based on SHA1. You shouldn't use this unless you're using
|
||||
/// very small keys, and this is the only one available to you. Even then,
|
||||
/// why are you using such small keys?!
|
||||
pub static SIGNING_HASH_SHA1: SigningHash = SigningHash {
|
||||
name: "SHA1",
|
||||
ident: &[0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,
|
||||
0x02,0x1a,0x05,0x00,0x04,0x14],
|
||||
run: runsha1
|
||||
};
|
||||
|
||||
fn runsha1(i: &[u8]) -> Vec<u8> {
|
||||
let mut d = Sha1::default();
|
||||
d.process(i);
|
||||
d.fixed_result().as_slice().to_vec()
|
||||
}
|
||||
|
||||
/// Sign a hash based on SHA2-224. This is the first reasonable choice
|
||||
/// we've come across, and is useful when you have smaller RSA key sizes.
|
||||
/// I wouldn't recommend it, though.
|
||||
pub static SIGNING_HASH_SHA224: SigningHash = SigningHash {
|
||||
name: "SHA224",
|
||||
ident: &[0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,
|
||||
0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,
|
||||
0x1c],
|
||||
run: runsha224
|
||||
};
|
||||
|
||||
fn runsha224(i: &[u8]) -> Vec<u8> {
|
||||
let mut d = Sha224::default();
|
||||
d.process(i);
|
||||
d.fixed_result().as_slice().to_vec()
|
||||
}
|
||||
|
||||
/// Sign a hash based on SHA2-256. The first one I'd recommend!
|
||||
pub static SIGNING_HASH_SHA256: SigningHash = SigningHash {
|
||||
name: "SHA256",
|
||||
ident: &[0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,
|
||||
0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,
|
||||
0x20],
|
||||
run: runsha256
|
||||
};
|
||||
|
||||
fn runsha256(i: &[u8]) -> Vec<u8> {
|
||||
let mut d = Sha256::default();
|
||||
d.process(i);
|
||||
d.fixed_result().as_slice().to_vec()
|
||||
}
|
||||
|
||||
/// Sign a hash based on SHA2-384. Approximately 50% better than
|
||||
/// SHA-256.
|
||||
pub static SIGNING_HASH_SHA384: SigningHash = SigningHash {
|
||||
name: "SHA384",
|
||||
ident: &[0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,
|
||||
0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,
|
||||
0x30],
|
||||
run: runsha384
|
||||
};
|
||||
|
||||
fn runsha384(i: &[u8]) -> Vec<u8> {
|
||||
let mut d = Sha384::default();
|
||||
d.process(i);
|
||||
d.fixed_result().as_slice().to_vec()
|
||||
}
|
||||
|
||||
/// Sign a hash based on SHA2-512. At this point, you're getting a bit
|
||||
/// silly. But if you want to through 8kbit RSA keys with a 512 bit SHA2
|
||||
/// signing hash, we're totally behind you.
|
||||
pub static SIGNING_HASH_SHA512: SigningHash = SigningHash {
|
||||
name: "SHA512",
|
||||
ident: &[0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,
|
||||
0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,
|
||||
0x40],
|
||||
run: runsha512
|
||||
};
|
||||
|
||||
fn runsha512(i: &[u8]) -> Vec<u8> {
|
||||
let mut d = Sha512::default();
|
||||
d.process(i);
|
||||
d.fixed_result().as_slice().to_vec()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user