Rewrite against a newer cryptonum.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -19,3 +19,7 @@ Cargo.lock
|
|||||||
**/gen
|
**/gen
|
||||||
**/.cabal-sandbox
|
**/.cabal-sandbox
|
||||||
**/cabal.sandbox.config
|
**/cabal.sandbox.config
|
||||||
|
FlameGraph
|
||||||
|
*.user_stacks
|
||||||
|
**/.ghc.environment.*
|
||||||
|
tests/rsa/dist*
|
||||||
@@ -10,6 +10,7 @@ repository = "https://github.com/acw/simple_crypto"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "^1.2.3"
|
byteorder = "^1.2.3"
|
||||||
|
cryptonum = { path = "../cryptonum" }
|
||||||
digest = "^0.7.1"
|
digest = "^0.7.1"
|
||||||
num = "^0.1.42"
|
num = "^0.1.42"
|
||||||
rand = "^0.3"
|
rand = "^0.3"
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
//! when they should use it, and examples. For now, it mostly just fowards
|
//! when they should use it, and examples. For now, it mostly just fowards
|
||||||
//! off to more detailed modules. Help requested!
|
//! off to more detailed modules. Help requested!
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate cryptonum;
|
||||||
extern crate digest;
|
extern crate digest;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
|
||||||
extern crate quickcheck;
|
extern crate quickcheck;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
@@ -20,12 +20,10 @@ extern crate sha1;
|
|||||||
extern crate sha2;
|
extern crate sha2;
|
||||||
extern crate simple_asn1;
|
extern crate simple_asn1;
|
||||||
|
|
||||||
/// The `cryptonum` module provides support for large numbers at fixed,
|
|
||||||
/// cryptographically-relevant sizes.
|
|
||||||
pub mod cryptonum;
|
|
||||||
/// The `rsa` module provides bare-bones support for RSA signing, verification,
|
/// The `rsa` module provides bare-bones support for RSA signing, verification,
|
||||||
/// encryption, decryption, and key generation.
|
/// encryption, decryption, and key generation.
|
||||||
pub mod rsa;
|
pub mod rsa;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod testing;
|
mod testing;
|
||||||
|
mod utils;
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ pub use self::public::{RSAPublic, RSAPublicKey,
|
|||||||
RSA3072Public, RSA4096Public, RSA8192Public,
|
RSA3072Public, RSA4096Public, RSA8192Public,
|
||||||
RSA15360Public};
|
RSA15360Public};
|
||||||
|
|
||||||
use cryptonum::*;
|
use cryptonum::signed::{ModInv};
|
||||||
|
use cryptonum::unsigned::{U256,U512,U1024,U1536,U2048,U3072,U4096,U7680,U8192,U15360};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
macro_rules! generate_rsa_pair
|
macro_rules! generate_rsa_pair
|
||||||
@@ -64,10 +65,12 @@ macro_rules! generate_rsa_pair
|
|||||||
loop {
|
loop {
|
||||||
let e = $uint::from(65537u32);
|
let e = $uint::from(65537u32);
|
||||||
let (p, q) = $pair::generate_pq(rng, &e);
|
let (p, q) = $pair::generate_pq(rng, &e);
|
||||||
let one = $half::from(1u32);
|
let one: $half = $half::from(1u32);
|
||||||
let phi = &(&p - &one) * &(&q - &one);
|
let pminus1: $half = &p - &one;
|
||||||
|
let qminus1: $half = &q - &one;
|
||||||
|
let phi: $uint = pminus1 * qminus1;
|
||||||
let n = &p * &q;
|
let n = &p * &q;
|
||||||
if let Some(d) = e.modinv(phi) {
|
if let Some(d) = e.modinv(&phi) {
|
||||||
let public = $pub::new(n.clone(), e);
|
let public = $pub::new(n.clone(), e);
|
||||||
let private = $priv::new(n, d);
|
let private = $priv::new(n, d);
|
||||||
return $pair::new(public, private);
|
return $pair::new(public, private);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use cryptonum::*;
|
use cryptonum::unsigned::*;
|
||||||
use digest::{FixedOutput,Input};
|
use digest::{FixedOutput,Input};
|
||||||
use rsa::core::{drop0s,pkcs1_pad,xor_vecs};
|
use rsa::core::{drop0s,pkcs1_pad,xor_vecs};
|
||||||
use rsa::errors::RSAError;
|
use rsa::errors::RSAError;
|
||||||
@@ -55,7 +55,7 @@ macro_rules! generate_rsa_private
|
|||||||
|
|
||||||
impl RSAPrivateKey<$num> for $rsa {
|
impl RSAPrivateKey<$num> for $rsa {
|
||||||
fn new(n: $num, d: $num) -> $rsa {
|
fn new(n: $num, d: $num) -> $rsa {
|
||||||
let nu = $bar::new(&n);
|
let nu = $bar::new(n.clone());
|
||||||
$rsa { nu: nu, d: d }
|
$rsa { nu: nu, d: d }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,12 +157,12 @@ generate_rsa_private!(RSA8192Private, U8192, BarrettU8192, 8192);
|
|||||||
generate_rsa_private!(RSA15360Private, U15360, BarrettU15360, 15360);
|
generate_rsa_private!(RSA15360Private, U15360, BarrettU15360, 15360);
|
||||||
|
|
||||||
macro_rules! generate_tests {
|
macro_rules! generate_tests {
|
||||||
( $( ($mod: ident, $rsa: ident, $num: ident, $size: expr) ),* ) => {
|
( $( ($mod: ident, $rsa: ident, $num: ident, $bar: ident, $num64: ident, $size: expr) ),* ) => {
|
||||||
$(
|
$(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
mod $mod {
|
mod $mod {
|
||||||
use cryptonum::Decoder;
|
use cryptonum::unsigned::Decoder;
|
||||||
use super::*;
|
use super::*;
|
||||||
use testing::run_test;
|
use testing::run_test;
|
||||||
use rsa::signing_hashes::*;
|
use rsa::signing_hashes::*;
|
||||||
@@ -172,17 +172,22 @@ macro_rules! generate_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn sign() {
|
fn sign() {
|
||||||
let fname = format!("tests/rsa/rsa{}.test", $size);
|
let fname = format!("tests/rsa/rsa{}.test", $size);
|
||||||
run_test(fname.to_string(), 6, |case| {
|
run_test(fname.to_string(), 8, |case| {
|
||||||
let (neg0, dbytes) = case.get("d").unwrap();
|
let (neg0, dbytes) = case.get("d").unwrap();
|
||||||
let (neg1, nbytes) = case.get("n").unwrap();
|
let (neg1, nbytes) = case.get("n").unwrap();
|
||||||
let (neg2, hbytes) = case.get("h").unwrap();
|
let (neg2, hbytes) = case.get("h").unwrap();
|
||||||
let (neg3, mbytes) = case.get("m").unwrap();
|
let (neg3, mbytes) = case.get("m").unwrap();
|
||||||
let (neg4, sbytes) = case.get("s").unwrap();
|
let (neg4, sbytes) = case.get("s").unwrap();
|
||||||
|
let (neg5, ubytes) = case.get("u").unwrap();
|
||||||
|
let (neg6, kbytes) = case.get("k").unwrap();
|
||||||
|
|
||||||
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4);
|
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4&&!neg5&&!neg6);
|
||||||
let n = $num::from_bytes(nbytes);
|
let n = $num64::from_bytes(nbytes);
|
||||||
|
let nu = $num64::from_bytes(ubytes);
|
||||||
|
let bigk = $num::from_bytes(kbytes);
|
||||||
|
let k = usize::from(bigk);
|
||||||
let d = $num::from_bytes(dbytes);
|
let d = $num::from_bytes(dbytes);
|
||||||
let privkey = $rsa::new(n, d);
|
let privkey = $rsa{ nu: $bar::from_components(k, n, nu), d: d };
|
||||||
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
||||||
let sighash = match hashnum {
|
let sighash = match hashnum {
|
||||||
0x160 => &SIGNING_HASH_SHA1,
|
0x160 => &SIGNING_HASH_SHA1,
|
||||||
@@ -200,17 +205,22 @@ macro_rules! generate_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn decrypt() {
|
fn decrypt() {
|
||||||
let fname = format!("tests/rsa/rsa{}.test", $size);
|
let fname = format!("tests/rsa/rsa{}.test", $size);
|
||||||
run_test(fname.to_string(), 6, |case| {
|
run_test(fname.to_string(), 8, |case| {
|
||||||
let (neg0, dbytes) = case.get("d").unwrap();
|
let (neg0, dbytes) = case.get("d").unwrap();
|
||||||
let (neg1, nbytes) = case.get("n").unwrap();
|
let (neg1, nbytes) = case.get("n").unwrap();
|
||||||
let (neg2, hbytes) = case.get("h").unwrap();
|
let (neg2, hbytes) = case.get("h").unwrap();
|
||||||
let (neg3, mbytes) = case.get("m").unwrap();
|
let (neg3, mbytes) = case.get("m").unwrap();
|
||||||
let (neg4, cbytes) = case.get("c").unwrap();
|
let (neg4, cbytes) = case.get("c").unwrap();
|
||||||
|
let (neg5, ubytes) = case.get("u").unwrap();
|
||||||
|
let (neg6, kbytes) = case.get("k").unwrap();
|
||||||
|
|
||||||
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4);
|
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4&&!neg5&&!neg6);
|
||||||
let n = $num::from_bytes(nbytes);
|
let n = $num64::from_bytes(nbytes);
|
||||||
|
let nu = $num64::from_bytes(ubytes);
|
||||||
|
let bigk = $num::from_bytes(kbytes);
|
||||||
|
let k = usize::from(bigk);
|
||||||
let d = $num::from_bytes(dbytes);
|
let d = $num::from_bytes(dbytes);
|
||||||
let privkey = $rsa::new(n, d);
|
let privkey = $rsa{ nu: $bar::from_components(k, n, nu), d: d };
|
||||||
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
||||||
let empty = "".to_string();
|
let empty = "".to_string();
|
||||||
match hashnum {
|
match hashnum {
|
||||||
@@ -253,11 +263,11 @@ macro_rules! generate_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_tests!( (RSA512, RSA512Private, U512, 512),
|
generate_tests!( (RSA512, RSA512Private, U512, BarrettU512, U576, 512),
|
||||||
(RSA1024, RSA1024Private, U1024, 1024),
|
(RSA1024, RSA1024Private, U1024, BarrettU1024, U1088, 1024),
|
||||||
(RSA2048, RSA2048Private, U2048, 2048),
|
(RSA2048, RSA2048Private, U2048, BarrettU2048, U2112, 2048),
|
||||||
(RSA3072, RSA3072Private, U3072, 3072),
|
(RSA3072, RSA3072Private, U3072, BarrettU3072, U3136, 3072),
|
||||||
(RSA4096, RSA4096Private, U4096, 4096),
|
(RSA4096, RSA4096Private, U4096, BarrettU4096, U4160, 4096),
|
||||||
(RSA8192, RSA8192Private, U8192, 8192),
|
(RSA8192, RSA8192Private, U8192, BarrettU8192, U8256, 8192),
|
||||||
(RSA15360, RSA15360Private, U15360, 15360)
|
(RSA15360, RSA15360Private, U15360, BarrettU15360, U15424, 15360)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use cryptonum::*;
|
use cryptonum::unsigned::*;
|
||||||
use digest::{FixedOutput,Input};
|
use digest::{FixedOutput,Input};
|
||||||
use num::{BigInt,BigUint};
|
use num::BigInt;
|
||||||
use rand::{OsRng,Rng};
|
use rand::{OsRng,Rng};
|
||||||
use rsa::core::{decode_biguint,pkcs1_pad,xor_vecs};
|
use rsa::core::{decode_biguint,pkcs1_pad,xor_vecs};
|
||||||
use rsa::errors::RSAError;
|
use rsa::errors::RSAError;
|
||||||
@@ -8,6 +8,9 @@ use rsa::oaep::OAEPParams;
|
|||||||
use rsa::signing_hashes::SigningHash;
|
use rsa::signing_hashes::SigningHash;
|
||||||
use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr,
|
use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr,
|
||||||
ASN1Class,FromASN1,ToASN1};
|
ASN1Class,FromASN1,ToASN1};
|
||||||
|
#[cfg(test)]
|
||||||
|
use std::fmt;
|
||||||
|
use utils::TranslateNums;
|
||||||
|
|
||||||
pub trait RSAPublicKey<N> {
|
pub trait RSAPublicKey<N> {
|
||||||
/// Generate a new public key pair for the given modulus and
|
/// Generate a new public key pair for the given modulus and
|
||||||
@@ -84,49 +87,51 @@ impl FromASN1 for RSAPublic {
|
|||||||
let nsize = n.bits();
|
let nsize = n.bits();
|
||||||
let mut rsa_size = 512;
|
let mut rsa_size = 512;
|
||||||
|
|
||||||
|
println!("n': {:X}", n);
|
||||||
|
println!("nsize: {}", nsize);
|
||||||
while rsa_size < nsize {
|
while rsa_size < nsize {
|
||||||
rsa_size = rsa_size + 256;
|
rsa_size = rsa_size + 256;
|
||||||
}
|
}
|
||||||
match rsa_size {
|
match rsa_size {
|
||||||
512 => {
|
512 => {
|
||||||
let n2 = U512::from(n);
|
let n2 = U512::from_num(n);
|
||||||
let e2 = U512::from(e);
|
let e2 = U512::from_num(e);
|
||||||
let res = RSA512Public::new(n2, e2);
|
let res = RSA512Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key512(res), rest))
|
Ok((RSAPublic::Key512(res), rest))
|
||||||
}
|
}
|
||||||
1024 => {
|
1024 => {
|
||||||
let n2 = U1024::from(n);
|
let n2 = U1024::from_num(n);
|
||||||
let e2 = U1024::from(e);
|
let e2 = U1024::from_num(e);
|
||||||
let res = RSA1024Public::new(n2, e2);
|
let res = RSA1024Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key1024(res), rest))
|
Ok((RSAPublic::Key1024(res), rest))
|
||||||
}
|
}
|
||||||
2048 => {
|
2048 => {
|
||||||
let n2 = U2048::from(n);
|
let n2 = U2048::from_num(n);
|
||||||
let e2 = U2048::from(e);
|
let e2 = U2048::from_num(e);
|
||||||
let res = RSA2048Public::new(n2, e2);
|
let res = RSA2048Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key2048(res), rest))
|
Ok((RSAPublic::Key2048(res), rest))
|
||||||
}
|
}
|
||||||
3072 => {
|
3072 => {
|
||||||
let n2 = U3072::from(n);
|
let n2 = U3072::from_num(n);
|
||||||
let e2 = U3072::from(e);
|
let e2 = U3072::from_num(e);
|
||||||
let res = RSA3072Public::new(n2, e2);
|
let res = RSA3072Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key3072(res), rest))
|
Ok((RSAPublic::Key3072(res), rest))
|
||||||
}
|
}
|
||||||
4096 => {
|
4096 => {
|
||||||
let n2 = U4096::from(n);
|
let n2 = U4096::from_num(n);
|
||||||
let e2 = U4096::from(e);
|
let e2 = U4096::from_num(e);
|
||||||
let res = RSA4096Public::new(n2, e2);
|
let res = RSA4096Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key4096(res), rest))
|
Ok((RSAPublic::Key4096(res), rest))
|
||||||
}
|
}
|
||||||
8192 => {
|
8192 => {
|
||||||
let n2 = U8192::from(n);
|
let n2 = U8192::from_num(n);
|
||||||
let e2 = U8192::from(e);
|
let e2 = U8192::from_num(e);
|
||||||
let res = RSA8192Public::new(n2, e2);
|
let res = RSA8192Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key8192(res), rest))
|
Ok((RSAPublic::Key8192(res), rest))
|
||||||
}
|
}
|
||||||
15360 => {
|
15360 => {
|
||||||
let n2 = U15360::from(n);
|
let n2 = U15360::from_num(n);
|
||||||
let e2 = U15360::from(e);
|
let e2 = U15360::from_num(e);
|
||||||
let res = RSA15360Public::new(n2, e2);
|
let res = RSA15360Public::new(n2, e2);
|
||||||
Ok((RSAPublic::Key15360(res), rest))
|
Ok((RSAPublic::Key15360(res), rest))
|
||||||
}
|
}
|
||||||
@@ -170,16 +175,17 @@ impl ToASN1 for RSAPublic {
|
|||||||
macro_rules! generate_rsa_public
|
macro_rules! generate_rsa_public
|
||||||
{
|
{
|
||||||
($rsa: ident, $num: ident, $bar: ident, $var: ident, $size: expr) => {
|
($rsa: ident, $num: ident, $bar: ident, $var: ident, $size: expr) => {
|
||||||
#[derive(Debug,PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct $rsa {
|
pub struct $rsa {
|
||||||
|
n: $num,
|
||||||
nu: $bar,
|
nu: $bar,
|
||||||
e: $num
|
e: $num
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RSAPublicKey<$num> for $rsa {
|
impl RSAPublicKey<$num> for $rsa {
|
||||||
fn new(n: $num, e: $num) -> $rsa {
|
fn new(n: $num, e: $num) -> $rsa {
|
||||||
let nu = $bar::new(&n);
|
let nu = $bar::new(n.clone());
|
||||||
$rsa { nu: nu, e: e }
|
$rsa { n: n, nu: nu, e: e }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8])
|
fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8])
|
||||||
@@ -292,14 +298,25 @@ macro_rules! generate_rsa_public
|
|||||||
fn to_asn1_class(&self, c: ASN1Class)
|
fn to_asn1_class(&self, c: ASN1Class)
|
||||||
-> Result<Vec<ASN1Block>,Self::Error>
|
-> Result<Vec<ASN1Block>,Self::Error>
|
||||||
{
|
{
|
||||||
let n = BigInt::from(BigUint::from(self.nu.m.clone()));
|
let n = BigInt::from(self.n.to_num());
|
||||||
let e = BigInt::from(BigUint::from(self.e.clone()));
|
let e = BigInt::from(self.e.to_num());
|
||||||
let enc_n = ASN1Block::Integer(c, 0, n);
|
let enc_n = ASN1Block::Integer(c, 0, n);
|
||||||
let enc_e = ASN1Block::Integer(c, 0, e);
|
let enc_e = ASN1Block::Integer(c, 0, e);
|
||||||
let seq = ASN1Block::Sequence(c, 0, vec![enc_n, enc_e]);
|
let seq = ASN1Block::Sequence(c, 0, vec![enc_n, enc_e]);
|
||||||
Ok(vec![seq])
|
Ok(vec![seq])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl fmt::Debug for $rsa {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
fmt.debug_struct(stringify!($rsa))
|
||||||
|
.field("n", &self.n)
|
||||||
|
.field("nu", &self.nu)
|
||||||
|
.field("e", &self.e)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,12 +329,12 @@ generate_rsa_public!(RSA8192Public, U8192, BarrettU8192, Key8192, 8192);
|
|||||||
generate_rsa_public!(RSA15360Public, U15360, BarrettU15360, Key15360, 15360);
|
generate_rsa_public!(RSA15360Public, U15360, BarrettU15360, Key15360, 15360);
|
||||||
|
|
||||||
macro_rules! generate_tests {
|
macro_rules! generate_tests {
|
||||||
( $( ($mod: ident, $rsa: ident, $num: ident, $size: expr) ),* ) => {
|
( $( ($mod: ident, $rsa: ident, $num: ident, $bar: ident, $num64: ident, $size: expr) ),* ) => {
|
||||||
$(
|
$(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
mod $mod {
|
mod $mod {
|
||||||
use cryptonum::Decoder;
|
use cryptonum::unsigned::Decoder;
|
||||||
use super::*;
|
use super::*;
|
||||||
use testing::run_test;
|
use testing::run_test;
|
||||||
use rsa::signing_hashes::*;
|
use rsa::signing_hashes::*;
|
||||||
@@ -325,13 +342,20 @@ macro_rules! generate_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn encode() {
|
fn encode() {
|
||||||
let fname = format!("tests/rsa/rsa{}.test", $size);
|
let fname = format!("tests/rsa/rsa{}.test", $size);
|
||||||
run_test(fname.to_string(), 6, |case| {
|
run_test(fname.to_string(), 8, |case| {
|
||||||
let (neg0, nbytes) = case.get("n").unwrap();
|
let (neg0, nbytes) = case.get("n").unwrap();
|
||||||
|
let (neg1, ubytes) = case.get("u").unwrap();
|
||||||
|
let (neg2, kbytes) = case.get("k").unwrap();
|
||||||
|
|
||||||
assert!(!neg0);
|
assert!(!neg0&&!neg1&&!neg2);
|
||||||
let n = $num::from_bytes(nbytes);
|
let n = $num::from_bytes(nbytes);
|
||||||
|
println!("n: {:X}", n);
|
||||||
|
let n64 = $num64::from(&n);
|
||||||
|
let nu = $num64::from_bytes(ubytes);
|
||||||
|
let bigk = $num::from_bytes(kbytes);
|
||||||
|
let k = usize::from(bigk);
|
||||||
let e = $num::from(65537u64);
|
let e = $num::from(65537u64);
|
||||||
let pubkey = $rsa::new(n, e);
|
let pubkey = $rsa{ n: n, nu: $bar::from_components(k, n64, nu), e: e };
|
||||||
let asn1 = pubkey.to_asn1().unwrap();
|
let asn1 = pubkey.to_asn1().unwrap();
|
||||||
let (pubkey2, _) = $rsa::from_asn1(&asn1).unwrap();
|
let (pubkey2, _) = $rsa::from_asn1(&asn1).unwrap();
|
||||||
assert_eq!(pubkey, pubkey2);
|
assert_eq!(pubkey, pubkey2);
|
||||||
@@ -341,16 +365,22 @@ macro_rules! generate_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn verify() {
|
fn verify() {
|
||||||
let fname = format!("tests/rsa/rsa{}.test", $size);
|
let fname = format!("tests/rsa/rsa{}.test", $size);
|
||||||
run_test(fname.to_string(), 6, |case| {
|
run_test(fname.to_string(), 8, |case| {
|
||||||
let (neg0, nbytes) = case.get("n").unwrap();
|
let (neg0, nbytes) = case.get("n").unwrap();
|
||||||
let (neg1, hbytes) = case.get("h").unwrap();
|
let (neg1, hbytes) = case.get("h").unwrap();
|
||||||
let (neg2, mbytes) = case.get("m").unwrap();
|
let (neg2, mbytes) = case.get("m").unwrap();
|
||||||
let (neg3, sbytes) = case.get("s").unwrap();
|
let (neg3, sbytes) = case.get("s").unwrap();
|
||||||
|
let (neg4, ubytes) = case.get("u").unwrap();
|
||||||
|
let (neg5, kbytes) = case.get("k").unwrap();
|
||||||
|
|
||||||
assert!(!neg0 && !neg1 && !neg2 && !neg3);
|
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5);
|
||||||
let n = $num::from_bytes(nbytes);
|
let n = $num::from_bytes(nbytes);
|
||||||
|
let n64 = $num64::from(&n);
|
||||||
|
let nu = $num64::from_bytes(ubytes);
|
||||||
|
let bigk = $num::from_bytes(kbytes);
|
||||||
|
let k = usize::from(bigk);
|
||||||
let e = $num::from(65537u64);
|
let e = $num::from(65537u64);
|
||||||
let pubkey = $rsa::new(n, e);
|
let pubkey = $rsa{ n: n, nu: $bar::from_components(k, n64, nu), e: e };
|
||||||
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
||||||
let sighash = match hashnum {
|
let sighash = match hashnum {
|
||||||
0x160 => &SIGNING_HASH_SHA1,
|
0x160 => &SIGNING_HASH_SHA1,
|
||||||
@@ -367,16 +397,22 @@ macro_rules! generate_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn encrypt() {
|
fn encrypt() {
|
||||||
let fname = format!("tests/rsa/rsa{}.test", $size);
|
let fname = format!("tests/rsa/rsa{}.test", $size);
|
||||||
run_test(fname.to_string(), 6, |case| {
|
run_test(fname.to_string(), 8, |case| {
|
||||||
let (neg0, nbytes) = case.get("n").unwrap();
|
let (neg0, nbytes) = case.get("n").unwrap();
|
||||||
let (neg1, hbytes) = case.get("h").unwrap();
|
let (neg1, hbytes) = case.get("h").unwrap();
|
||||||
let (neg2, mbytes) = case.get("m").unwrap();
|
let (neg2, mbytes) = case.get("m").unwrap();
|
||||||
let (neg3, sbytes) = case.get("s").unwrap();
|
let (neg3, sbytes) = case.get("s").unwrap();
|
||||||
|
let (neg4, ubytes) = case.get("u").unwrap();
|
||||||
|
let (neg5, kbytes) = case.get("k").unwrap();
|
||||||
|
|
||||||
assert!(!neg0 && !neg1 && !neg2 && !neg3);
|
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5);
|
||||||
let n = $num::from_bytes(nbytes);
|
let n = $num::from_bytes(nbytes);
|
||||||
|
let n64 = $num64::from(&n);
|
||||||
|
let nu = $num64::from_bytes(ubytes);
|
||||||
|
let bigk = $num::from_bytes(kbytes);
|
||||||
|
let k = usize::from(bigk);
|
||||||
let e = $num::from(65537u64);
|
let e = $num::from(65537u64);
|
||||||
let pubkey = $rsa::new(n, e);
|
let pubkey = $rsa{ n: n, nu: $bar::from_components(k, n64, nu), e: e };
|
||||||
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
let hashnum = ((hbytes[0] as u16)<<8) + (hbytes[1] as u16);
|
||||||
let sighash = match hashnum {
|
let sighash = match hashnum {
|
||||||
0x160 => &SIGNING_HASH_SHA1,
|
0x160 => &SIGNING_HASH_SHA1,
|
||||||
@@ -394,11 +430,11 @@ macro_rules! generate_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_tests!( (RSA512, RSA512Public, U512, 512),
|
generate_tests!( (RSA512, RSA512Public, U512, BarrettU512, U576, 512),
|
||||||
(RSA1024, RSA1024Public, U1024, 1024),
|
(RSA1024, RSA1024Public, U1024, BarrettU1024, U1088, 1024),
|
||||||
(RSA2048, RSA2048Public, U2048, 2048),
|
(RSA2048, RSA2048Public, U2048, BarrettU2048, U2112, 2048),
|
||||||
(RSA3072, RSA3072Public, U3072, 3072),
|
(RSA3072, RSA3072Public, U3072, BarrettU3072, U3136, 3072),
|
||||||
(RSA4096, RSA4096Public, U4096, 4096),
|
(RSA4096, RSA4096Public, U4096, BarrettU4096, U4160, 4096),
|
||||||
(RSA8192, RSA8192Public, U8192, 8192),
|
(RSA8192, RSA8192Public, U8192, BarrettU8192, U8256, 8192),
|
||||||
(RSA15360, RSA15360Public, U15360, 15360)
|
(RSA15360, RSA15360Public, U15360, BarrettU15360, U15424, 15360)
|
||||||
);
|
);
|
||||||
41
src/utils.rs
Normal file
41
src/utils.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
use cryptonum::unsigned::*;
|
||||||
|
use num::BigUint;
|
||||||
|
|
||||||
|
pub trait TranslateNums {
|
||||||
|
fn from_num(x: BigUint) -> Self;
|
||||||
|
fn to_num(&self) -> BigUint;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! from_biguint {
|
||||||
|
($uname: ident, $size: expr) => {
|
||||||
|
impl TranslateNums for $uname {
|
||||||
|
fn from_num(x: BigUint) -> $uname {
|
||||||
|
let mut base_vec = x.to_bytes_be();
|
||||||
|
let target_bytes = $size / 8;
|
||||||
|
|
||||||
|
while target_bytes > base_vec.len() {
|
||||||
|
base_vec.insert(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while base_vec.len() > target_bytes {
|
||||||
|
base_vec.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uname::from_bytes(&base_vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_num(&self) -> BigUint {
|
||||||
|
let bytes = self.to_bytes();
|
||||||
|
BigUint::from_bytes_be(&bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
from_biguint!(U512, 512);
|
||||||
|
from_biguint!(U1024, 1024);
|
||||||
|
from_biguint!(U2048, 2048);
|
||||||
|
from_biguint!(U3072, 3072);
|
||||||
|
from_biguint!(U4096, 4096);
|
||||||
|
from_biguint!(U8192, 8192);
|
||||||
|
from_biguint!(U15360, 15360);
|
||||||
5
tests/rsa/CHANGELOG.md
Normal file
5
tests/rsa/CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Revision history for genrsa
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
||||||
13
tests/rsa/LICENSE
Normal file
13
tests/rsa/LICENSE
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Copyright (c) 2018 Adam Wick
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
2
tests/rsa/Setup.hs
Normal file
2
tests/rsa/Setup.hs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Distribution.Simple
|
||||||
|
main = defaultMain
|
||||||
21
tests/rsa/genrsa.cabal
Normal file
21
tests/rsa/genrsa.cabal
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: genrsa
|
||||||
|
version: 0.1.0.0
|
||||||
|
-- synopsis:
|
||||||
|
-- description:
|
||||||
|
license: ISC
|
||||||
|
license-file: LICENSE
|
||||||
|
author: Adam Wick
|
||||||
|
maintainer: awick@uhsure.com
|
||||||
|
-- copyright:
|
||||||
|
category: Math
|
||||||
|
build-type: Simple
|
||||||
|
extra-source-files: CHANGELOG.md
|
||||||
|
cabal-version: >=1.10
|
||||||
|
|
||||||
|
executable genrsa
|
||||||
|
main-is: genrsa.hs
|
||||||
|
-- other-modules:
|
||||||
|
-- other-extensions:
|
||||||
|
build-depends: base >=4.11 && <4.12, RSA >=2.3 && <2.4, crypto-api >=0.13 && <0.14, bytestring >=0.10 && <0.11, containers >=0.5 && <0.6
|
||||||
|
-- hs-source-dirs:
|
||||||
|
default-language: Haskell2010
|
||||||
@@ -63,6 +63,8 @@ genCase g0 size =
|
|||||||
(Right sig, Right (cipher, g4)) ->
|
(Right sig, Right (cipher, g4)) ->
|
||||||
(Map.fromList [("d", Numeric.showHex d ""),
|
(Map.fromList [("d", Numeric.showHex d ""),
|
||||||
("n", Numeric.showHex n ""),
|
("n", Numeric.showHex n ""),
|
||||||
|
("k", Numeric.showHex (computeK n) ""),
|
||||||
|
("u", Numeric.showHex (barrett n) "" ),
|
||||||
("h", show hashlen),
|
("h", show hashlen),
|
||||||
("m", showBytes msg),
|
("m", showBytes msg),
|
||||||
("s", showBytes sig),
|
("s", showBytes sig),
|
||||||
@@ -72,6 +74,20 @@ genCase g0 size =
|
|||||||
(_, _) ->
|
(_, _) ->
|
||||||
genCase g3 size
|
genCase g3 size
|
||||||
|
|
||||||
|
base :: Integer
|
||||||
|
base = 2 ^ (64 :: Integer)
|
||||||
|
|
||||||
|
barrett :: Integer -> Integer
|
||||||
|
barrett m = (base ^ (2 * k)) `div` m
|
||||||
|
where
|
||||||
|
k = computeK m
|
||||||
|
|
||||||
|
computeK :: Integer -> Int
|
||||||
|
computeK v = go 0 1
|
||||||
|
where
|
||||||
|
go k acc | v <= acc = k
|
||||||
|
| otherwise = go (k + 1) (acc * base)
|
||||||
|
|
||||||
go :: CryptoRandomGen g => g -> Handle -> Int -> Int -> IO ()
|
go :: CryptoRandomGen g => g -> Handle -> Int -> Int -> IO ()
|
||||||
go _ _ _ 0 = return ()
|
go _ _ _ 0 = return ()
|
||||||
go g hndl size count =
|
go g hndl size count =
|
||||||
10500
tests/rsa/rsa1024.test
10500
tests/rsa/rsa1024.test
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10500
tests/rsa/rsa2048.test
10500
tests/rsa/rsa2048.test
File diff suppressed because it is too large
Load Diff
10500
tests/rsa/rsa3072.test
10500
tests/rsa/rsa3072.test
File diff suppressed because it is too large
Load Diff
10500
tests/rsa/rsa4096.test
10500
tests/rsa/rsa4096.test
File diff suppressed because it is too large
Load Diff
10500
tests/rsa/rsa512.test
10500
tests/rsa/rsa512.test
File diff suppressed because one or more lines are too long
10500
tests/rsa/rsa8192.test
10500
tests/rsa/rsa8192.test
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user