diff --git a/Cargo.toml b/Cargo.toml index 6f16edb..099f61e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,8 @@ name = "cryptonum" version = "0.1.0" authors = ["awick"] +edition = "2018" [dependencies] -quickcheck = "^0.7.2" -rand = "^0.6.0" \ No newline at end of file +# quickcheck = "^0.7.2" +# rand = "^0.6.0" \ No newline at end of file diff --git a/generation/LICENSE b/generation/LICENSE new file mode 100644 index 0000000..7afdcb8 --- /dev/null +++ b/generation/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2019 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. diff --git a/generation/Setup.hs b/generation/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/generation/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/generation/generation.cabal b/generation/generation.cabal new file mode 100644 index 0000000..bc9b96f --- /dev/null +++ b/generation/generation.cabal @@ -0,0 +1,29 @@ +cabal-version: 2.0 +-- Initial package description 'generation.cabal' generated by 'cabal +-- init'. For further documentation, see +-- http://haskell.org/cabal/users-guide/ + +name: generation +version: 0.1.0.0 +synopsis: Generates the cryptonum Rust library, based on requirements. +homepage: http://github.com/acw/cryptonum +license: ISC +license-file: LICENSE +author: Adam Wick +maintainer: awick@uhsure.com +copyright: 2019 +category: Math +build-type: Simple +extra-source-files: CHANGELOG.md + +executable generation + main-is: Main.hs + other-modules: Gen, Requirements, UnsignedBase + -- other-extensions: + build-depends: base ^>=4.12.0.0, + containers, + directory, + filepath, + mtl + hs-source-dirs: src + default-language: Haskell2010 diff --git a/generation/src/Gen.hs b/generation/src/Gen.hs new file mode 100644 index 0000000..421a24d --- /dev/null +++ b/generation/src/Gen.hs @@ -0,0 +1,73 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +module Gen( + Gen(Gen), + runGen, + gensym, + indent, + blank, + out, + wrapIndent, + ) + where + +import Control.Monad.RWS.Strict(RWS,evalRWS) +import Control.Monad.State.Class(MonadState,get,put) +import Control.Monad.Writer.Class(MonadWriter,tell) +import Data.List(replicate) +import Data.Word(Word) + +newtype Gen a = Gen { unGen :: RWS () String GenState a} + deriving (Applicative, Functor, Monad, MonadState GenState, MonadWriter String) + +tabAmount :: Word +tabAmount = 4 + +data GenState = GenState { + indentAmount :: Word, + gensymIndex :: Word +} + +initGenState :: GenState +initGenState = GenState { indentAmount = 0, gensymIndex = 0 } + +runGen :: FilePath -> Gen a -> IO a +runGen path action = + do let (res, contents) = evalRWS (unGen action) () initGenState + writeFile path contents + return res + +gensym :: String -> Gen String +gensym prefix = + do gs <- get + let gs' = gs{ gensymIndex = gensymIndex gs + 1 } + put gs' + return (prefix ++ show (gensymIndex gs)) + +indent :: Gen a -> Gen a +indent action = + do gs <- get + put gs{ indentAmount = indentAmount gs + tabAmount } + res <- action + put gs + return res + +blank :: Gen () +blank = tell "\n" + +out :: String -> Gen () +out val = + do gs <- get + tell (replicate (fromIntegral (indentAmount gs)) ' ') + tell val + tell "\n" + +wrapIndent :: String -> Gen a -> Gen a +wrapIndent val middle = + do gs <- get + tell (replicate (fromIntegral (indentAmount gs)) ' ') + tell val + tell " {\n" + res <- indent middle + tell (replicate (fromIntegral (indentAmount gs)) ' ') + tell "}\n" + return res \ No newline at end of file diff --git a/generation/src/Main.hs b/generation/src/Main.hs new file mode 100644 index 0000000..373ffbf --- /dev/null +++ b/generation/src/Main.hs @@ -0,0 +1,32 @@ +module Main + where + +import Control.Monad(forM_,unless) +import Data.List(sort) +import Data.Map.Strict(Map) +import qualified Data.Map.Strict as Map +import Gen(runGen) +import Requirements(Requirement(..), Operation(..), requirements) +import System.Directory(createDirectoryIfMissing) +import System.Environment(getArgs) +import System.Exit(die) +import System.FilePath(()) +import UnsignedBase(declareBaseStructure) + +gatherRequirements :: [Requirement] -> Map Int [Operation] +gatherRequirements = foldr process Map.empty + where process (Req x val) = Map.insertWith (++) x [val] + +main :: IO () +main = + do args <- getArgs + unless (length args == 1) $ + die ("generation takes exactly one argument, the target directory") + let reqs = sort (Map.toList (gatherRequirements requirements)) + target = head args + forM_ reqs $ \ (size, opes) -> + do let basedir = target "unsigned" ("u" ++ show size) + createDirectoryIfMissing True basedir + forM_ reqs $ \ (x, ops) -> + do runGen (basedir "mod.rs") (declareBaseStructure size ops) + \ No newline at end of file diff --git a/generation/src/Requirements.hs b/generation/src/Requirements.hs new file mode 100644 index 0000000..f832c8f --- /dev/null +++ b/generation/src/Requirements.hs @@ -0,0 +1,278 @@ +module Requirements( + Operation(..), + Requirement(..), + requirements + ) + where + +import Data.List(sort) + +data Operation = Add + | BaseOps + | Barretts + | Div + | ModDiv + | ModExp + | ModMul + | ModSq + | Mul + | Scale + | Shifts + | Square + | Sub + | Convert Int + | SignedAdd + | SignedBase + | SignedCmp + | SignedShift + | SignedSub + | SignedMul + | SignedDiv + | SignedModInv + | SignedScale + | SigConvert Int + | SquareRoot + | EGCD + | ModInv + | PrimeGen + | RSA + | DSA + | ECDSA + deriving (Eq, Ord, Show) + +data Requirement = Req Int Operation + deriving (Eq, Ord, Show) + +data Need = Need Operation (Int -> [Requirement]) + +needs :: [Need] +needs = [ Need RSA (\ size -> [Req (size `div` 2) Sub, + Req (size `div` 2) Mul, + Req (size `div` 2) PrimeGen, + Req size BaseOps, + Req size ModInv, + Req size ModExp + ]) + , Need DSA (\ size -> [Req size BaseOps, + Req size Shifts, + Req size Add, + Req size SquareRoot, + Req size PrimeGen, + Req size ModInv, + Req size Mul, + Req (size * 2) Add, + Req (((size * 2) + 64) * 2) Div, + Req size (Convert 512), + Req size (Convert (size + 128)), + Req size (Convert ((size * 2) + 64)), + Req size (Convert (((size * 2) + 64) * 2)) + ]) + , Need ECDSA (\ size -> [Req size SignedSub, + Req size SignedMul, + Req size ModMul, + Req size ModDiv, + Req (size * 2) BaseOps, + Req (size * 2) SignedBase, + Req (size * 2) SignedShift, + Req (size * 2) SignedSub, + Req (size * 2) SignedMul, + Req (size * 2) SignedDiv, + Req ((size * 2) + 64) SignedBase, + Req ((size * 2) + 64) BaseOps, + Req ((size * 2) + 64) SignedAdd, + Req ((size * 2) + 64) SignedShift, + Req ((size * 2) + 64) ModDiv, + Req size (Convert (size * 2)), + Req size (SigConvert (size * 2)), + Req size (Convert ((size * 2) + 64)), + Req size (SigConvert ((size * 2) + 64)), + Req (size * 2) (Convert ((size * 2) + 64)), + Req (size * 2) (SigConvert ((size * 2) + 64)), + Req size (Convert (size * 4)), + Req (size * 4) Div + ]) + , Need PrimeGen (\ size -> [Req size Div, + Req size Shifts, + Req size ModExp, + Req size EGCD]) + , Need Add (\ size -> [Req size BaseOps, + Req (size + 64) BaseOps, + Req size (Convert (size + 64)) + ]) + , Need Barretts (\ size -> [Req size BaseOps, + Req (size + 64) BaseOps, + Req (size * 2) BaseOps, + Req ((size * 2) + 64) BaseOps, + Req size (Convert ((size * 2) + 64)), + Req (size + 64) Mul, + Req ((size * 2) + 64) Add, + Req ((size * 2) + 64) Sub, + Req (size + 64) (Convert ((size * 2) + 64)), + Req ((size * 2) + 64) (Convert ((size + 64) * 2)), + Req (size * 2) (Convert ((size * 2) + 64)), + Req (size + 64) (Convert ((size + 64) * 2)), + Req (size + 64) (Convert (size * 2)), + Req (size * 2) Shifts, + Req ((size + 64) * 2) Shifts, + Req ((size * 2) + 64) Div + ]) + , Need Div (\ size -> [Req size BaseOps, + Req (size * 2) BaseOps, + Req size (Convert (size * 2)), + Req (size * 2) Sub, + Req size Mul, + Req 192 BaseOps, + Req 192 Mul, + Req 384 BaseOps + ]) + , Need ModExp (\ size -> [Req size BaseOps, + Req size Barretts, + Req size ModSq, + Req size ModMul, + Req size (Convert (size + 64)) + ]) + , Need ModMul (\ size -> [Req size BaseOps, + Req (size * 2) BaseOps, + Req size Barretts, + Req size Mul, + Req size (Convert (size + 64)) + ]) + , Need ModDiv (\ size -> [Req size ModInv, + Req size SignedModInv, + Req size SignedMul, + Req size SignedDiv, + Req (size * 2) SignedDiv, + Req size (SigConvert (size * 2)) + ]) + , Need ModSq (\ size -> [Req size BaseOps, + Req (size * 2) BaseOps, + Req size Barretts, + Req size Square, + Req (size * 2) Div, + Req size (Convert (size * 2)), + Req size (Convert (size + 64)) + ]) + , Need Mul (\ size -> [Req size BaseOps, + Req size Scale, + Req (size * 2) BaseOps, + Req size (Convert (size * 2)) + ]) + , Need Scale (\ size -> [Req (size + 64) BaseOps]) + , Need Shifts (\ size -> [Req size BaseOps + ]) + , Need Square (\ size -> [Req size BaseOps, + Req (size * 2) BaseOps + ]) + , Need Sub (\ size -> [Req size BaseOps + ]) + , Need SignedAdd (\ size -> [Req size SignedBase, + Req size Add, + Req size Sub, + Req (size + 64) SignedBase, + Req (size + 64) BaseOps + ]) + , Need SignedBase (\ size -> [Req size BaseOps]) + , Need SignedCmp (\ size -> [Req size BaseOps]) + , Need SignedShift (\ size -> [Req size SignedBase, + Req size BaseOps, + Req size Shifts, + Req size Add + ]) + , Need SignedSub (\ size -> [Req size SignedBase, + Req (size + 64) SignedBase, + Req (size + 64) BaseOps, + Req size Add, + Req size Sub, + Req (size + 64) Sub, + Req size (Convert (size + 64)), + Req size (SigConvert (size + 64)) + ]) + , Need SignedMul (\ size -> [Req size Mul, + Req size SignedScale, + Req (size * 2) SignedBase, + Req size (SigConvert (size * 2)), + Req size Square + ]) + , Need SignedDiv (\ size -> [Req size Div, + Req size Add + ]) + , Need EGCD (\ size -> [Req size SignedBase, + Req size BaseOps, + Req size Shifts, + Req (size + 64) SignedBase, + Req ((size + 64) * 2) SignedBase, + Req size (SigConvert (size + 64)), + Req (size + 64) SignedShift, + Req (size + 64) SignedAdd, + Req (size + 64) SignedSub, + Req (size + 64) SignedCmp, + Req (size + 64) SignedDiv, + Req (size + 64) SignedMul, + Req ((size + 64) * 2) SignedSub, + Req (size + 64) (Convert (((size + 64) * 2) + 64)), + Req (size + 64) (SigConvert (((size + 64) * 2) + 64)) + ]) + , Need ModInv (\ size -> [Req size BaseOps, + Req (size + 64) SignedBase, + Req (size + 64) BaseOps, + Req size (Convert (size + 64)), + Req size EGCD, + Req (size + 64) SignedAdd, + Req size Barretts + ]) + , Need SignedModInv (\ size -> [ + Req size EGCD, + Req size SignedModInv + ]) + , Need SquareRoot (\ size -> [Req size BaseOps, + Req size Shifts, + Req size Add, + Req size Sub + ]) + ] + +newRequirements :: Requirement -> [Requirement] +newRequirements (Req size op) = concatMap go needs ++ [Req size BaseOps] + where + go (Need op2 generator) | op == op2 = generator size + | otherwise = [] + +rsaSizes :: [Int] +rsaSizes = [512,1024,2048,3072,4096,8192,15360] + +dsaSizes :: [Int] +dsaSizes = [192,256,1024,2048,3072] + +ecdsaSizes :: [Int] +ecdsaSizes = [192,256,384,576] + +baseRequirements :: [Requirement] +baseRequirements = concatMap (\ x -> [Req x RSA]) rsaSizes + ++ concatMap (\ x -> [Req x DSA]) dsaSizes + ++ concatMap (\ x -> [Req x ECDSA]) ecdsaSizes + ++ [Req 192 (Convert 1024), Req 256 (Convert 2048), Req 256 (Convert 3072)] -- used in DSA + ++ [Req 384 (Convert 1024), Req 512 (Convert 2048), Req 512 (Convert 3072)] -- used in DSA + ++ [Req 192 Add, Req 256 Add, Req 384 Add] -- used for testing + ++ [Req 192 Mul, Req 384 Mul] -- used for testing + ++ [Req 448 (Convert 512)] -- used for testing + +requirements :: [Requirement] +requirements = go baseRequirements + where + step ls = let news = concatMap newRequirements ls + ls' = concatMap sanitizeConverts (news ++ ls) + ls'' = removeDups (sort ls') + in ls'' + -- + go ls = let ls' = step ls + in if ls == ls' then ls else go ls' + -- + removeDups [] = [] + removeDups (x:xs) | x `elem` xs = removeDups xs + | otherwise = x : removeDups xs + -- + sanitizeConverts (Req x (Convert y)) + | x == y = [] + | x < y = [Req x (Convert y), Req y BaseOps] + | otherwise = [Req y (Convert x), Req x BaseOps] + sanitizeConverts x = [x] diff --git a/generation/src/UnsignedBase.hs b/generation/src/UnsignedBase.hs new file mode 100644 index 0000000..77b4a29 --- /dev/null +++ b/generation/src/UnsignedBase.hs @@ -0,0 +1,89 @@ +module UnsignedBase( + declareBaseStructure + ) + where + +import Control.Monad(forM_) +import Gen +import Requirements(Operation) + +declareBaseStructure :: Int -> [Operation] -> Gen () +declareBaseStructure bitsize ops = + do let name = "U" ++ show bitsize + entries = bitsize `div` 64 + top = entries - 1 + out "use core::cmp::{Eq,Ordering,PartialEq,min};" + out "use core::fmt;" + out "use super::super::CryptoNum;" + blank + out "mod binary_ops;" + blank + wrapIndent ("pub struct " ++ name) $ + out ("value: [u64; " ++ show entries ++ "]") + blank + wrapIndent ("impl CryptoNum for " ++ name) $ + do wrapIndent ("fn zero() -> Self") $ + out (name ++ "{ value: [0; " ++ show entries ++ "] }") + blank + wrapIndent ("fn is_zero(&self) -> bool") $ + do forM_ (reverse [1..top]) $ \ i -> + out ("self.value[" ++ show i ++ "] == 0 &&") + out "self.value[0] == 0" + blank + wrapIndent ("fn is_even(&self) -> bool") $ + out "self.value[0] & 0x1 == 0" + blank + wrapIndent ("fn is_odd(&self) -> bool") $ + out "self.value[0] & 0x1 == 0" + blank + wrapIndent ("fn bit_length() -> usize") $ + out (show bitsize) + blank + wrapIndent ("fn mask(&mut self, len: usize)") $ + do out ("let dellen = min(len, " ++ show entries ++ ");") + wrapIndent ("for i in dellen.." ++ show entries) $ + out ("self.value[i] = 0;") + blank + wrapIndent ("fn testbit(&self, bit: usize) -> bool") $ + do out "let idx = bit / 64;" + out "let offset = bit % 64;" + wrapIndent ("if idx >= " ++ show entries) $ + out "return false;" + out "(self.value[idx] & (1u64 << offset)) != 0" + blank + wrapIndent ("impl PartialEq for " ++ name) $ + wrapIndent "fn eq(&self, other: &Self) -> bool" $ + do forM_ (reverse [1..top]) $ \ i -> + out ("self.value[" ++ show i ++ "] == other.value[" ++ show i ++ "] && ") + out "self.value[0] == other.value[0]" + blank + out ("impl Eq for " ++ name ++ " {}") + blank + wrapIndent ("impl Ord for " ++ name) $ + wrapIndent "fn cmp(&self, other: &Self) -> Ordering" $ + do out ("self.value[" ++ show top ++ "].cmp(&other.value[" ++ show top ++ "])") + forM_ (reverse [0..top-1]) $ \ i -> + out (" .then(self.value[" ++ show i ++ "].cmp(&other.value[" ++ show i ++ "]))") + blank + wrapIndent ("impl PartialOrd for " ++ name) $ + wrapIndent "fn partial_cmp(&self, other: &Self) -> Option" $ + out "Some(self.cmp(other))" + blank + wrapIndent ("impl fmt::Debug for " ++ name) $ + wrapIndent "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result" $ + do out ("f.debug_tuple(" ++ show name ++ ")") + forM_ [0..top] $ \ i -> + out (" .field(&self.value[" ++ show i ++ "])") + out " .finish()" + blank + wrapIndent ("impl fmt::UpperHex for " ++ name) $ + wrapIndent "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result" $ + do forM_ (reverse [1..top]) $ \ i -> + out ("write!(f, \"{:X}\", self.value[" ++ show i ++ "])?;") + out "write!(f, \"{:X}\", self.value[0])" + blank + wrapIndent ("impl fmt::LowerHex for " ++ name) $ + wrapIndent "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result" $ + do forM_ (reverse [1..top]) $ \ i -> + out ("write!(f, \"{:x}\", self.value[" ++ show i ++ "])?;") + out "write!(f, \"{:x}\", self.value[0])" \ No newline at end of file diff --git a/src/signed/add.rs b/old/signed/add.rs similarity index 100% rename from src/signed/add.rs rename to old/signed/add.rs diff --git a/src/signed/base.rs b/old/signed/base.rs similarity index 100% rename from src/signed/base.rs rename to old/signed/base.rs diff --git a/src/signed/compare.rs b/old/signed/compare.rs similarity index 100% rename from src/signed/compare.rs rename to old/signed/compare.rs diff --git a/src/signed/conversion.rs b/old/signed/conversion.rs similarity index 100% rename from src/signed/conversion.rs rename to old/signed/conversion.rs diff --git a/src/signed/div.rs b/old/signed/div.rs similarity index 100% rename from src/signed/div.rs rename to old/signed/div.rs diff --git a/src/signed/egcd.rs b/old/signed/egcd.rs similarity index 100% rename from src/signed/egcd.rs rename to old/signed/egcd.rs diff --git a/src/signed/invoc.rs b/old/signed/invoc.rs similarity index 100% rename from src/signed/invoc.rs rename to old/signed/invoc.rs diff --git a/old/signed/mod.rs b/old/signed/mod.rs new file mode 100644 index 0000000..be0bf84 --- /dev/null +++ b/old/signed/mod.rs @@ -0,0 +1,52 @@ +//! This module includes a large number of signed integer types for very +//! large integers, designed to try to match good performance with a high +//! assurance threshold. +//! +//! The types provided in this module, and the functions available for each +//! of those types, is derived from standard bit widths for RSA, DSA, and +//! Elliptic Curve encryption schemes. If this library does not include a +//! function you would like for another cryptographic scheme, please reach +//! out to the authors; in many cases, the relevant code can be automatically +//! generated. +//! +#[macro_use] +mod add; +#[macro_use] +mod base; +#[macro_use] +mod compare; +#[macro_use] +mod conversion; +#[macro_use] +mod div; +#[macro_use] +mod egcd; +#[macro_use] +mod moddiv; +#[macro_use] +mod modinv; +#[macro_use] +mod mul; +#[macro_use] +mod scale; +#[macro_use] +mod shift; +#[macro_use] +mod subtraction; + +use quickcheck::{Arbitrary,Gen}; +use std::cmp::{Ord,Ordering,PartialOrd}; +use std::fmt; +use std::ops::{Add,AddAssign}; +use std::ops::{Div,DivAssign}; +use std::ops::{Mul,MulAssign}; +use std::ops::{Rem,RemAssign}; +use std::ops::{Shl,ShlAssign,Shr,ShrAssign}; +use std::ops::{Sub,SubAssign}; +use unsigned::*; + +pub use self::egcd::EGCD; +pub use self::moddiv::ModDiv; +pub use self::modinv::ModInv; + +include!("invoc.rs"); \ No newline at end of file diff --git a/src/signed/moddiv.rs b/old/signed/moddiv.rs similarity index 100% rename from src/signed/moddiv.rs rename to old/signed/moddiv.rs diff --git a/src/signed/modinv.rs b/old/signed/modinv.rs similarity index 100% rename from src/signed/modinv.rs rename to old/signed/modinv.rs diff --git a/src/signed/mul.rs b/old/signed/mul.rs similarity index 100% rename from src/signed/mul.rs rename to old/signed/mul.rs diff --git a/src/signed/scale.rs b/old/signed/scale.rs similarity index 100% rename from src/signed/scale.rs rename to old/signed/scale.rs diff --git a/src/signed/shift.rs b/old/signed/shift.rs similarity index 100% rename from src/signed/shift.rs rename to old/signed/shift.rs diff --git a/src/signed/subtraction.rs b/old/signed/subtraction.rs similarity index 100% rename from src/signed/subtraction.rs rename to old/signed/subtraction.rs diff --git a/src/unsigned/add.rs b/old/unsigned/add.rs similarity index 100% rename from src/unsigned/add.rs rename to old/unsigned/add.rs diff --git a/src/unsigned/barrett.rs b/old/unsigned/barrett.rs similarity index 100% rename from src/unsigned/barrett.rs rename to old/unsigned/barrett.rs diff --git a/src/unsigned/base.rs b/old/unsigned/base.rs similarity index 100% rename from src/unsigned/base.rs rename to old/unsigned/base.rs diff --git a/src/unsigned/cmp.rs b/old/unsigned/cmp.rs similarity index 100% rename from src/unsigned/cmp.rs rename to old/unsigned/cmp.rs diff --git a/src/unsigned/codec.rs b/old/unsigned/codec.rs similarity index 100% rename from src/unsigned/codec.rs rename to old/unsigned/codec.rs diff --git a/src/unsigned/conversion.rs b/old/unsigned/conversion.rs similarity index 100% rename from src/unsigned/conversion.rs rename to old/unsigned/conversion.rs diff --git a/src/unsigned/div.rs b/old/unsigned/div.rs similarity index 100% rename from src/unsigned/div.rs rename to old/unsigned/div.rs diff --git a/src/unsigned/formatter.rs b/old/unsigned/formatter.rs similarity index 100% rename from src/unsigned/formatter.rs rename to old/unsigned/formatter.rs diff --git a/src/unsigned/invoc.rs b/old/unsigned/invoc.rs similarity index 100% rename from src/unsigned/invoc.rs rename to old/unsigned/invoc.rs diff --git a/old/unsigned/mod.rs b/old/unsigned/mod.rs new file mode 100644 index 0000000..dcfe4f5 --- /dev/null +++ b/old/unsigned/mod.rs @@ -0,0 +1,104 @@ +//! This module includes a large number of unsigned integer types for very +//! large integers, designed to try to match good performance with a high +//! assurance threshold. +//! +//! The types provided in this module, and the functions available for each +//! of those types, is derived from standard bit widths for RSA, DSA, and +//! Elliptic Curve encryption schemes. If this library does not include a +//! function you would like for another cryptographic scheme, please reach +//! out to the authors; in many cases, the relevant code can be automatically +//! generated. +//! +//! For performance reasons, we also include support for Barrett reduction, +//! which should improve the speed of modular reduction of large numbers for +//! those cases in which you will be frequently performing modulo operations +//! using the same modulus. +#[macro_use] +mod add; +#[macro_use] +mod barrett; +#[macro_use] +mod base; +#[macro_use] +mod cmp; +#[macro_use] +mod codec; +#[macro_use] +mod conversion; +#[macro_use] +mod div; +#[macro_use] +mod formatter; +#[macro_use] +mod modexp; +#[macro_use] +mod modmul; +#[macro_use] +mod modsq; +#[macro_use] +mod mul; +#[macro_use] +mod primes; +#[macro_use] +mod rand; +#[macro_use] +mod scale; +#[macro_use] +mod shifts; +#[macro_use] +mod sqrt; +#[macro_use] +mod square; +#[macro_use] +mod sub; + +pub use self::base::CryptoNum; +pub use self::codec::{Encoder,Decoder}; +pub use self::div::DivMod; +pub use self::modexp::ModExp; +pub use self::modmul::ModMul; +pub use self::modsq::ModSquare; +pub use self::primes::PrimeGen; +pub use self::square::Square; +pub use self::sqrt::SquareRoot; + +pub(crate) use self::add::unsafe_addition; +pub(crate) use self::scale::scale; + +use rand::{Rng,RngCore}; +use rand::distributions::{Distribution,Standard}; +use rand::distributions::uniform::*; +use self::add::addition; +use self::cmp::compare; +use self::codec::raw_decoder; +use self::div::get_number_size; +use self::formatter::tochar; +use self::mul::{multiply,multiply_small}; +use self::primes::SMALL_PRIMES; +use self::shifts::{shiftl,shiftr}; +use self::sub::subtract; +use std::cmp::{Ordering,min}; +use std::fmt; +use std::fmt::Write; +use std::ops::{Add,AddAssign}; +use std::ops::{Mul,MulAssign}; +use std::ops::{Div,DivAssign}; +use std::ops::{Rem,RemAssign}; +use std::ops::{Shl,ShlAssign,Shr,ShrAssign}; +use std::ops::{Sub,SubAssign}; +use std::ops::{BitAnd,BitOr}; + +use quickcheck::{Arbitrary,Gen}; + +macro_rules! base_impls +{ + ($name: ident, $size: expr) => { + generate_base!($name, $size); + generate_base_conversions!($name); + generate_codec!($name); + generate_formatter!($name); + cmp_impls!($name); + } +} + +include!("invoc.rs"); diff --git a/src/unsigned/modexp.rs b/old/unsigned/modexp.rs similarity index 100% rename from src/unsigned/modexp.rs rename to old/unsigned/modexp.rs diff --git a/src/unsigned/modmul.rs b/old/unsigned/modmul.rs similarity index 100% rename from src/unsigned/modmul.rs rename to old/unsigned/modmul.rs diff --git a/src/unsigned/modsq.rs b/old/unsigned/modsq.rs similarity index 100% rename from src/unsigned/modsq.rs rename to old/unsigned/modsq.rs diff --git a/src/unsigned/mul.rs b/old/unsigned/mul.rs similarity index 100% rename from src/unsigned/mul.rs rename to old/unsigned/mul.rs diff --git a/src/unsigned/primes.rs b/old/unsigned/primes.rs similarity index 100% rename from src/unsigned/primes.rs rename to old/unsigned/primes.rs diff --git a/src/unsigned/rand.rs b/old/unsigned/rand.rs similarity index 100% rename from src/unsigned/rand.rs rename to old/unsigned/rand.rs diff --git a/src/unsigned/scale.rs b/old/unsigned/scale.rs similarity index 100% rename from src/unsigned/scale.rs rename to old/unsigned/scale.rs diff --git a/src/unsigned/shifts.rs b/old/unsigned/shifts.rs similarity index 100% rename from src/unsigned/shifts.rs rename to old/unsigned/shifts.rs diff --git a/src/unsigned/sqrt.rs b/old/unsigned/sqrt.rs similarity index 100% rename from src/unsigned/sqrt.rs rename to old/unsigned/sqrt.rs diff --git a/src/unsigned/square.rs b/old/unsigned/square.rs similarity index 100% rename from src/unsigned/square.rs rename to old/unsigned/square.rs diff --git a/src/unsigned/sub.rs b/old/unsigned/sub.rs similarity index 100% rename from src/unsigned/sub.rs rename to old/unsigned/sub.rs diff --git a/src/lib.rs b/src/lib.rs index ed9436c..825ccdd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,49 +1,24 @@ -extern crate quickcheck; -extern crate rand; - +#![no_std] pub mod signed; pub mod unsigned; -#[cfg(test)] -pub mod testing; -#[cfg(test)] -mod arithmetic { - use super::signed::*; - use super::unsigned::*; +/// A trait definition for large numbers. +pub trait CryptoNum { + /// Generate a new value of the given type. + fn zero() -> Self; + /// Test if the number is zero. + fn is_zero(&self) -> bool; + /// Test if the number is even. + fn is_even(&self) -> bool; + /// Test if the number is odd. + fn is_odd(&self) -> bool; + /// The size of this number in bits. + fn bit_length() -> usize; + /// Mask off the high parts of the number. In particular, it + /// zeros the bits above (len * 64). + fn mask(&mut self, len: usize); + /// Test if the given bit is zero, where bits are numbered in + /// least-significant order (0 is the LSB, etc.). + fn testbit(&self, bit: usize) -> bool; +} - quickcheck! { - fn commutivity_signed_add(x: I576, y: I576) -> bool { - (&x + &y) == (&y + &x) - } - fn commutivity_unsigned_add(x: U576, y: U576) -> bool { - (&x + &y) == (&y + &x) - } - fn commutivity_unsigned_mul(x: U192, y: U192) -> bool { - (&x * &y) == (&y * &x) - } - - fn associativity_unsigned_add(x: U192, y: U192, z: U192) -> bool { - (U256::from(&x) + (&y + &z)) == ((&x + &y) + U256::from(&z)) - } - fn associativity_unsigned_mul(x: U192, y: U192, z: U192) -> bool { - (U384::from(&x) * (&y * &z)) == ((&x * &y) * U384::from(&z)) - } - - fn identity_signed_add(x: I576) -> bool { - (&x + I576::zero()) == I640::from(&x) - } - fn identity_unsigned_add(x: U576) -> bool { - (&x + U576::zero()) == U640::from(&x) - } - fn identity_unsigned_mul(x: U192) -> bool { - (&x * U192::from(1u64)) == U384::from(&x) - } - - fn additive_inverse(x: I576) -> bool { - (&x + x.negate()) == I640::zero() - } - fn distribution(x: U192, y: U192, z: U192) -> bool { - (U256::from(&x) * (&y + &z)) == U512::from((&x * &y) + (&x * &z)) - } - } -} \ No newline at end of file diff --git a/src/signed/mod.rs b/src/signed/mod.rs index be0bf84..e69de29 100644 --- a/src/signed/mod.rs +++ b/src/signed/mod.rs @@ -1,52 +0,0 @@ -//! This module includes a large number of signed integer types for very -//! large integers, designed to try to match good performance with a high -//! assurance threshold. -//! -//! The types provided in this module, and the functions available for each -//! of those types, is derived from standard bit widths for RSA, DSA, and -//! Elliptic Curve encryption schemes. If this library does not include a -//! function you would like for another cryptographic scheme, please reach -//! out to the authors; in many cases, the relevant code can be automatically -//! generated. -//! -#[macro_use] -mod add; -#[macro_use] -mod base; -#[macro_use] -mod compare; -#[macro_use] -mod conversion; -#[macro_use] -mod div; -#[macro_use] -mod egcd; -#[macro_use] -mod moddiv; -#[macro_use] -mod modinv; -#[macro_use] -mod mul; -#[macro_use] -mod scale; -#[macro_use] -mod shift; -#[macro_use] -mod subtraction; - -use quickcheck::{Arbitrary,Gen}; -use std::cmp::{Ord,Ordering,PartialOrd}; -use std::fmt; -use std::ops::{Add,AddAssign}; -use std::ops::{Div,DivAssign}; -use std::ops::{Mul,MulAssign}; -use std::ops::{Rem,RemAssign}; -use std::ops::{Shl,ShlAssign,Shr,ShrAssign}; -use std::ops::{Sub,SubAssign}; -use unsigned::*; - -pub use self::egcd::EGCD; -pub use self::moddiv::ModDiv; -pub use self::modinv::ModInv; - -include!("invoc.rs"); \ No newline at end of file diff --git a/src/unsigned/mod.rs b/src/unsigned/mod.rs index dcfe4f5..76a166d 100644 --- a/src/unsigned/mod.rs +++ b/src/unsigned/mod.rs @@ -1,104 +1 @@ -//! This module includes a large number of unsigned integer types for very -//! large integers, designed to try to match good performance with a high -//! assurance threshold. -//! -//! The types provided in this module, and the functions available for each -//! of those types, is derived from standard bit widths for RSA, DSA, and -//! Elliptic Curve encryption schemes. If this library does not include a -//! function you would like for another cryptographic scheme, please reach -//! out to the authors; in many cases, the relevant code can be automatically -//! generated. -//! -//! For performance reasons, we also include support for Barrett reduction, -//! which should improve the speed of modular reduction of large numbers for -//! those cases in which you will be frequently performing modulo operations -//! using the same modulus. -#[macro_use] -mod add; -#[macro_use] -mod barrett; -#[macro_use] -mod base; -#[macro_use] -mod cmp; -#[macro_use] -mod codec; -#[macro_use] -mod conversion; -#[macro_use] -mod div; -#[macro_use] -mod formatter; -#[macro_use] -mod modexp; -#[macro_use] -mod modmul; -#[macro_use] -mod modsq; -#[macro_use] -mod mul; -#[macro_use] -mod primes; -#[macro_use] -mod rand; -#[macro_use] -mod scale; -#[macro_use] -mod shifts; -#[macro_use] -mod sqrt; -#[macro_use] -mod square; -#[macro_use] -mod sub; - -pub use self::base::CryptoNum; -pub use self::codec::{Encoder,Decoder}; -pub use self::div::DivMod; -pub use self::modexp::ModExp; -pub use self::modmul::ModMul; -pub use self::modsq::ModSquare; -pub use self::primes::PrimeGen; -pub use self::square::Square; -pub use self::sqrt::SquareRoot; - -pub(crate) use self::add::unsafe_addition; -pub(crate) use self::scale::scale; - -use rand::{Rng,RngCore}; -use rand::distributions::{Distribution,Standard}; -use rand::distributions::uniform::*; -use self::add::addition; -use self::cmp::compare; -use self::codec::raw_decoder; -use self::div::get_number_size; -use self::formatter::tochar; -use self::mul::{multiply,multiply_small}; -use self::primes::SMALL_PRIMES; -use self::shifts::{shiftl,shiftr}; -use self::sub::subtract; -use std::cmp::{Ordering,min}; -use std::fmt; -use std::fmt::Write; -use std::ops::{Add,AddAssign}; -use std::ops::{Mul,MulAssign}; -use std::ops::{Div,DivAssign}; -use std::ops::{Rem,RemAssign}; -use std::ops::{Shl,ShlAssign,Shr,ShrAssign}; -use std::ops::{Sub,SubAssign}; -use std::ops::{BitAnd,BitOr}; - -use quickcheck::{Arbitrary,Gen}; - -macro_rules! base_impls -{ - ($name: ident, $size: expr) => { - generate_base!($name, $size); - generate_base_conversions!($name); - generate_codec!($name); - generate_formatter!($name); - cmp_impls!($name); - } -} - -include!("invoc.rs"); +mod u192; \ No newline at end of file