NTRU (empty) → 0.1.0.0
raw patch · 4 files changed
+602/−0 lines, 4 filesdep +SHAdep +arithmoidep +basesetup-changed
Dependencies added: SHA, arithmoi, base, bytestring, containers, crypto-api, polynomial, random, split
Files
- LICENSE +2/−0
- NTRU.cabal +54/−0
- NTRU.hs +544/−0
- Setup.hs +2/−0
+ LICENSE view
@@ -0,0 +1,2 @@+Do not steal+
+ NTRU.cabal view
@@ -0,0 +1,54 @@+-- Initial NTRU.cabal generated by cabal init. For further documentation, +-- see http://haskell.org/cabal/users-guide/++-- The name of the package.+name: NTRU++-- The package version. See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.1.0.0++-- A short (one-line) description of the package.+synopsis: NTRU Cryptographic Library ++-- A longer description of the package.+description: A Haskell implementation of the NTRU cryptographic system, following the IEEE Standard Specification for Public Key Crpytographic Techniques Based on Hard Problems over Lattices ++-- The license under which the package is released.+license: MIT ++-- The file containing the license text.+license-file: LICENSE++-- The package author(s).+author: Theo Levine++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer: tlevine@cyberpointllc.com++-- A copyright notice.+-- copyright: ++category: Cryptography++build-type: Simple++-- Constraint on the version of Cabal needed to build this package.+cabal-version: >=1.8+++library+ -- Modules exported by the library.+ exposed-modules: NTRU+ + -- Modules included in this library but not exported.+ -- other-modules: + + -- Other library packages from which modules are imported.+ build-depends: base ==4.6.*, SHA ==1.6.*, split ==0.2.*, containers ==0.5.*, crypto-api ==0.13.*, random ==1.0.*, polynomial ==0.6.*, arithmoi ==0.4.*, bytestring ==0.10.*+
+ NTRU.hs view
@@ -0,0 +1,544 @@+{- | +Module : NTRU+Description : NTRU cryptographic system implementation+Maintainer : tlevine@cyberpointllc.com+Stability : Experimental+License : MIT+This is an implementation of the NTRU cryptographic system, following the standard set forth +by the IEEE in the document entitled IEEE Standard Specification for Public Key Cryptographic +Techniques Based on Hard Problems over Lattices. It is designed to be compatible with the implmentation+of SecurityInnovations, available <https://www.securityinnovation.com/products/encryption-libraries/ntru-crypto/ here>. +-}++++module NTRU (keyGen112, keyGen128, keyGen192, keyGen256, encrypt112, encrypt128, encrypt192, encrypt256, decrypt112, decrypt128, decrypt192, decrypt256) where++import Data.Digest.Pure.SHA+import Data.List.Split+import Data.Sequence as Seq (index, update, empty, fromList, Seq)+import Data.Foldable as L (toList)+import Crypto.Random+import System.Random+import Math.Polynomial+import Math.NumberTheory.Moduli +import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as BC+import qualified Data.ByteString.Lazy as BL++{- Polynomial Operations -} ++-- | Poly to List+fromPoly :: (Num a, Eq a, Integral a) => Poly a -> [a]+fromPoly = polyCoeffs LE ++-- | List to Poly+toPoly :: (Num a, Eq a, Integral a) => [a] -> Poly a +toPoly = poly LE ++-- | Retrive the coefficient of p corresponding to the (x^i) term +polyCoef :: (Num a, Eq a, Integral a) => Poly a -> Int -> a+polyCoef p i = fromPoly p !! i ++-- | Useful for syntax. Allows for poly + poly or poly * poly. +-- | Note that for ring multiplication, reduceDegree must be called+instance (Num a, Eq a) => Num (Poly a) where+ f + g = addPoly f g+ f * g = multPoly f g+ negate = negatePoly+ abs = undefined+ signum = undefined+ fromInteger = undefined++-- | Allows for polynomial multiplaction in the ring of size n: reduceDegree (getDegree a) (a * b) = a * b in the ring+reduceDegree :: (Num a, Eq a, Integral a) => Int -> Poly a -> Poly a +reduceDegree n f =+ let (f1,f2) = splitAt n (fromPoly f) + in toPoly f1 + toPoly f2 ++-- | Reduces all of the polynomial's coefficents mod q+polyMod :: (Num a, Eq a, Integral a) => a -> Poly a -> Poly a+polyMod q f = toPoly $ map (`mod` q) (fromPoly f)++-- | Same as polyMod, but chooses representative group values in Z/nZ to be in [-q/2, q/2] instead of [0,q-1]+polyModInterval :: (Num a, Eq a, Integral a) => a -> Poly a -> Poly a+polyModInterval q f = toPoly $ map (\x -> intervalReduce $ x `mod` q) (fromPoly f) + where intervalReduce x = if x <= (q `div` 2) then x else x - q++-- | PolyMod when q is big +polyBigMod :: (Num a, Eq a, Integral a) => Int -> Poly a -> Poly a+polyBigMod q p = toPoly $ map fromIntegral $ fromPoly $ polyMod q $ toPoly $ map fromIntegral $ fromPoly p ++-- | Creates the polynomial x^n+xPow :: (Num a, Eq a, Integral a) => Int -> Poly a +xPow = powPoly x+++{- Key Generation -}++-- | 6.3.3.1 Divides one polynomial by another mod p: let (q,r) = divPolyMod p a b; ((b * q) + r) `mod` p = a +divPolyMod :: (Num a, Eq a, Integral a) => a -> Poly a -> Poly a -> (Poly a, Poly a)+divPolyMod p a b = + let n = polyDegree b in + let u = inverseMod (polyCoef b n) p in + divLoop p b n u zero a+ where + divLoop p b n u q r =+ let d = polyDegree r in + if d < n then (polyMod p q, polyMod p r)+ else+ let v = scalePoly (u * polyCoef r d) (xPow (d - n)) in + let r' = polyMod p $ r - (v * b) in + let q' = polyMod p $ q + v in + divLoop p b n u q' r'++-- | 6.3.3.2 Finds the extended GCD mod p: let (d,u) = extendedEuclidean p a b; if d == 1, then (u * a) `mod` p = 1 +extendedEuclidean :: (Num a, Eq a, Integral a) => a -> Poly a -> Poly a -> (Poly a, Poly a)+extendedEuclidean p a b = extendedEuclideanLoop p one a zero b+ where + extendedEuclideanLoop p u d v1 v3+ | polyIsZero v3 = (d,u)+ | otherwise = + let (q,t3) = divPolyMod p d v3 in + let t1 = polyMod p $ u - q * v1 in + extendedEuclideanLoop p v1 v3 t1 t3 ++-- | Generates Polynomials and Attempts to Find Inverses Until Success: let (a,u) = findInversable params; (a * u) `mod` 2 = 1 +findInversable :: (Num a, Eq a, Integral a) => [Int] -> IO (Poly a, Poly a)+findInversable params = do + let n = getN params + let df = getDf params + a' <- genRandPoly n df df + let a = scalePoly (getP params) a' + one+ let b = xPow n - one+ let (d, u) = extendedEuclidean 2 a b + if d == one then return (a, u) else findInversable params ++-- | 6.3.3.4 Raises Polynomial Inverse mod 2 to mod 2^11; let (a, u) = findInversable; (a * (inverseLift a b (degree a))) `mod` 2048 = 1 +inverseLift :: (Num a, Eq a, Integral a) => Poly a -> Poly a -> Int -> a -> Poly a+inverseLift a b deg = inverseLift' a b deg 2 11 where + inverseLift' a b deg n e q + | e == 0 = polyMod (2 ^ 11) b+ | otherwise = + let b' = polyBigMod (2 ^ n) $ scalePoly 2 b - (reduceDegree deg $! a * (reduceDegree deg $! (b * b))) + in inverseLift' a b' deg (2 * n) (e `div` 2) q ++-- | 9.2.1 Generates a key pair. (publicKey, privateKey). The private key will be 1 + pF, per enhancement 2 at +-- | https://www.securityinnovation.com/uploads/Crypto/NTRU%20Enhancements%201.pdf+generateKeyPair :: (Num a, Eq a, Integral a) => [Int] -> IO ([a], [a])+generateKeyPair params = do + let n = getN params + dg = getDg params+ q = getQ params + (f, u) <- findInversable params + let fq = inverseLift f u n (fromIntegral q) + g <- genRandPoly n dg (dg - 1) + let pk = polyMod q $! reduceDegree n $! scalePoly (getP params) $! fq * g+ return (fromPoly pk, fromPoly f)+++{- Blinding Polynomial Generation -}++-- | Creates seed for bpgm +genSData :: (Num a, Eq a, Integral a) => [a] -> [a] -> [a] -> [Int] -> [a]+genSData h msg b params = + let bh = concatMap bigIntToBits h in + let pkLen = getPkLen params in + let bhTrunc = take (pkLen - (pkLen `mod` 8)) bh in + let hTrunc = map (fromIntegral . bitsToInt) (chunksOf 8 bhTrunc) in + let sData = map fromIntegral (getOID params) ++ msg ++ b ++ hTrunc in + sData++-- | 8.3.2.2 Generates the blinding polynomial using the given seed+bpgm :: (Num a, Eq a, Integral a) => [a] -> [Int] -> [a]+bpgm seed params =+ let (i, s) = igf ([], [], 0) seed params in+ let r = Seq.update i 1 $ Seq.fromList $ replicate (getN params) 0 in+ let t = getDr params in+ let r' = rlooper s 1 r (t - 1) params in+ L.toList $ rlooper s (-1) r' t params++-- | Creates the sequence with the proper -1's and 1's+rlooper :: (Num a, Eq a, Integral a) => ([a], [a], a) -> a -> Seq.Seq a -> Int -> [Int] -> Seq.Seq a+rlooper s val r 0 params = r+rlooper s val r t params =+ let (i, s') = igf s [] params in+ if Seq.index r i == 0+ then (let r' = Seq.update i val r in rlooper s' val r' (t-1) params)+ else rlooper s' val r t params++-- | 8.4.2.1 Given a state or a seed, generates the next index to be used+igf :: (Num a, Eq a, Integral a) => ([a], [a], a) -> [a] -> [Int] -> (Int, ([a], [a], a))+igf state seed params =+ let (z, buf, counter) = extractVariables state seed params + (i, buf', counter') = genIndex counter buf z params+ s = (z, buf', counter')+ n = getN params + in (i `mod` n, s)++-- | Either initializes the state, or uses the already created one +extractVariables :: (Num a, Eq a, Integral a) => ([a], [a], a) -> [a] -> [Int] -> ([a], [a], a) +extractVariables state [] _ = state+extractVariables _ seed params = igfinit seed params ++-- | Initialization of state+igfinit :: (Num a, Eq a, Integral a) => [a] -> [Int] -> ([a], [a], a)+igfinit seed params = + let minCallsR = getMinCallsR params + shaFn = getSHA params + z = shaFn seed + buf = buildM 0 minCallsR z shaFn []+ in (z, buf, minCallsR)++-- | Returns an index and pieces of the state+genIndex :: (Num a, Eq a, Integral a) => a -> [a] -> [a] -> [Int] -> (Int, [a], a)+genIndex counter buf z params =+ let remLen = length buf+ c = getC params + n = getN params + shaFn = getSHA params+ hLen = getHLen params + tmpLen = (c - remLen)+ cThreshold = counter + fromIntegral (ceiling (fromIntegral tmpLen / fromIntegral hLen))+ (m, counter') = if remLen >= c + then (buf, counter)+ else (buildM counter cThreshold z shaFn buf, cThreshold)+ (b, buf') = splitAt c (buf ++ m)+ i = fromIntegral $ bitsToInt b + in if i >= (2^c - (2^c `mod` n))+ then genIndex counter' buf' z params + else (i, buf', counter')++-- | Builds out the buffer +buildM :: (Num a, Eq a, Integral a) => a -> a -> [a] -> ([a]->[a]) -> [a] -> [a]+buildM count cThreshold z shaFn buf+ | count >= cThreshold = buf + | otherwise = + let c = i2osp count 3 + h = shaFn (z ++ c) + m = buf ++ intsToBits h+ in buildM (count + 1) cThreshold z shaFn m ++-- | Converts counter to 4 bytes... Not exactly the same as documentation but in practice counter does not exceed the bounds+i2osp :: (Num a, Eq a, Integral a) => a -> a -> [a]+i2osp i n + | n == 0 = [i] + | otherwise = 0:i2osp i (n-1)+++{- SHA Functionality -}++-- | Needed to pass sha() output to unpack()+bToStrict :: BL.ByteString -> B.ByteString+bToStrict = B.concat . BL.toChunks++-- | sha1 output: 20 octets (1 octet = 8 bits)+sha1Octets :: (Num a, Eq a, Integral a) => [a] -> [a]+sha1Octets input = map fromIntegral $ B.unpack $ bToStrict $ bytestringDigest $ sha1 $ BL.pack $ map fromIntegral input++-- | sha256 output: 32 octets+sha256Octets :: (Num a, Eq a, Integral a) => [a] -> [a]+sha256Octets input = map fromIntegral $ B.unpack $ bToStrict $ bytestringDigest $ sha256 $ BL.pack $ map fromIntegral input+++{- Mask Generation -} -- Much of this code is similar to blinding polynomial generation, but we implemented separately ++-- | 8.4.1.1 Generates the mask based on the given seed +mgf :: (Num a, Eq a, Integral a) => [a] -> [Int] -> [a]+mgf seed params =+ let n = getN params in+ let shaFn = getSHA params in + let z = shaFn seed in + let buf = buildBuffer 0 (getMinCallsR params) z shaFn [] in + let i = formatI buf in+ take n $ finishI i n (getMinCallsR params) z shaFn++-- | Builds out the buffer +buildBuffer :: (Num a, Eq a, Integral a) => a -> a -> [a] -> ([a]->[a]) -> [a] -> [a]+buildBuffer counter minCallsR z shaFn buffer+ | counter >= minCallsR = buffer+ | otherwise = let octet_c = i2osp counter 3 in + let h = shaFn (z ++ octet_c) in + buildBuffer (counter + 1) minCallsR z shaFn (buffer ++ h)++-- | Step I Converts octets to trits+toTrits :: (Num a, Eq a, Integral a) => a -> a -> [a]+toTrits n o+ | n == 0 = []+ | otherwise = (o `mod` 3):toTrits (n - 1) ((o - (o `mod` 3)) `div` 3)++-- | Builds out buffer when needed+finishI :: (Num a, Eq a, Integral a) => [a] -> Int -> a -> [a] -> ([a] -> [a]) -> [a]+finishI i n counter z shaFn+ | fromIntegral (length i) >= n = i + | otherwise = let buf = buildBuffer counter (counter + 1) z shaFn [] in + let i' = formatI buf in + finishI i' n (counter + 1) z shaFn ++-- | Formats buffer+formatI :: (Num a, Eq a, Integral a) => [a] -> [a]+formatI buf = concatMap (toTrits 5) $ filter (< 243) buf++{- Encrypt -}++-- | 9.2.2 Encrypts msg using the public key h and parameter set +encrypt :: (Num a, Eq a, Integral a) => [Int] -> [a] -> [a] -> IO [a]+encrypt params msg h = + let l = fromIntegral $ length msg+ maxLength = getMaxMsgLenBytes params in+ if l > maxLength then error "message too long"+ else do + let bLen = getDb params `div` 8 + dr = getDr params + n = getN params+ q = getQ params+ p = getP params + b <- randByteString bLen+ let p0 = replicate (fromIntegral $ maxLength - l) 0+ m = b ++ [fromIntegral l] ++ msg ++ p0 + mBin = addPadding $ intsToBits m + mTrin = concatMap binToTern $ chunksOf 3 mBin+ sData = genSData h msg b params+ r = bpgm sData params+ r' = polyMod q $ reduceDegree n $ toPoly r * toPoly h+ r4 = polyMod 4 r'+ or4 = toOctets $ fromPoly r4+ mask = mgf or4 params + m' = polyModInterval p $ toPoly mask + toPoly mTrin+ e = polyMod q $ r' + m' + return $ fromPoly e+++{- Decrypt -}++-- | 9.3.3 Decrypts e using the private key f and verifies it using the public key h. +decrypt :: (Num a, Eq a, Integral a) => [Int] -> [a] -> [a] -> [a] -> [a]+decrypt params f h e =+ let n = getN params+ p = getP params+ q = getQ params + bLen = getDb params `div` 8+ ci = polyMod p $ polyModInterval q $ reduceDegree n $ toPoly f * toPoly e+ cR = polyMod q $ toPoly e - polyModInterval p ci+ cR4 = polyMod 4 cR+ coR4 = toOctets $ fromPoly cR4+ cMask = polyMod p $ toPoly $ mgf coR4 params+ cMTrin = polyModInterval p $ ci - cMask + cMTrin' = improperPolynomial n $ fromPoly cMTrin+ cMBin = concatMap ternToBin $ chunksOf 2 $ take (length cMTrin' - (length cMTrin' `mod` 2)) cMTrin'+ cM = map bitsToInt $ chunksOf 8 $ take (length cMBin - (length cMBin `mod` 8)) cMBin+ (cb, rest) = splitAt bLen cM+ ([cl], rest') = splitAt (getLLen params) rest+ (cm, rest'') = splitAt (fromIntegral cl) rest'+ sData = genSData h cm cb params + cr = bpgm sData params+ cR' = polyMod q $ reduceDegree n $ toPoly cr * toPoly h+ validR = cR' == cR+ validRemainder = all (==0) rest''+ in checkValid cm validR validRemainder ++-- | Checks results of verification steps+checkValid :: (Num a, Eq a, Integral a) => [a] -> Bool -> Bool -> [a]+checkValid _ _ False = error "Failure Checking Remainder of Message"+checkValid _ False _ = error "Failure Verifying Blinding Polynomial"+checkValid m _ _ = m +++{- Other Operations -}++-- | Calculate the modular inverse of x and y: ((inverseMod x y) * x) `mod` y = 1 +inverseMod :: (Num a, Eq a, Integral a) => a -> a -> a+inverseMod x y = case invertMod (fromIntegral x) (fromIntegral y) of+ Just n -> fromIntegral n + _ -> error "Coukd not calculate inverseMod"++-- | Generate a random ByteString+randByteString :: (Num a, Eq a, Integral a) => Int -> IO [a]+randByteString size = do+ g <- newGenIO :: IO SystemRandom+ case genBytes size g of + Left err -> error $ show err+ Right (result, g2) -> return (unpackByteString result)++-- | Converts a bytestring to a list of ascii values +unpackByteString :: (Num a, Eq a, Integral a) => BC.ByteString -> [a]+unpackByteString str = map fromIntegral (B.unpack str) ++-- | Used to encode bits of a message from binary to trinary representation +binToTern :: (Num a, Eq a, Integral a) => [a] -> [a]+binToTern [0,0,0] = [0,0]+binToTern [0,0,1] = [0,1]+binToTern [0,1,0] = [0,-1]+binToTern [0,1,1] = [1,0]+binToTern [1,0,0] = [1,1]+binToTern [1,0,1] = [1,-1]+binToTern [1,1,0] = [-1,0]+binToTern [1,1,1] = [-1,1]+binToTern _ = error "Problem converting binary to trinary"++-- | Inverse of binToTern+ternToBin :: (Num a, Eq a, Integral a) => [a] -> [a]+ternToBin [0,0] = [0,0,0]+ternToBin [0,1] = [0,0,1]+ternToBin [0,-1] = [0,1,0]+ternToBin [1,0] = [0,1,1]+ternToBin [1,1] = [1,0,0]+ternToBin [1,-1] = [1,0,1]+ternToBin [-1,0] = [1,1,0]+ternToBin [-1,1] = [1,1,1]+ternToBin _ = error " Problem converting trinary to binary"+++-- | Makes message length a multiple of 3 by padding with 0s+addPadding :: (Num a, Eq a, Integral a) => [a] -> [a]+addPadding m = case length m `mod` 3 of+ 0 -> m+ 1 -> m ++ [0,0]+ 2 -> m ++ [0]+++-- | Converts a single byte to a list of (n+1) bits: unpackByte 7 3 = [0,0,0,0,0,0,1,1]+unpackByte :: (Num a, Eq a, Integral a) => a -> a -> [a]+unpackByte n b + | n < 0 = []+ | otherwise = (b `div` (2 ^ n)):unpackByte (n-1) (b `mod` 2 ^ n)++-- | Converts a byte to a list of 8 bits+intToBits :: (Num a, Eq a, Integral a) => a -> [a]+intToBits = unpackByte 7++-- | Converts a byte to a list of 11 bits. Needed for blinding polynomial seed +bigIntToBits :: (Num a, Eq a, Integral a) => a -> [a]+bigIntToBits = unpackByte 10++-- | Turns a list of integers into bits +intsToBits :: (Num a, Eq a, Integral a) => [a] -> [a]+intsToBits = concatMap intToBits++-- | Converts a list of bits to a single byte: bitsToInt [0,0,0,0,0,0,1,1] = 3 +bitsToInt :: (Num a, Eq a, Integral a) => [a] -> a+bitsToInt b = packByte 1 (reverse b) + where+ packByte n b+ | null b = 0+ | otherwise = n * head b + packByte (n * 2) (tail b)++-- | Generates a random polynomial of degree n with pos 1's and neg -1's+genRandPoly :: (Num a, Eq a, Integral a) => Int -> Int -> Int -> IO (Poly a)+genRandPoly n pos neg = do + poly <- setRandValues [] n pos neg+ return $ toPoly poly + where+ setRandValues lst n pos neg = + if n == 0 then return lst + else do+ randVal <- randomIO :: IO Int+ let randInRange = randVal `mod` n + if randInRange <= pos then setRandValues ((-1):lst) (n - 1) (neg - 1) pos else if randInRange <= (pos + neg) then setRandValues (1:lst) (n - 1) neg (pos - 1) else setRandValues (0:lst) (n - 1) neg pos++-- | Creates an improper polynomial of length n from poly+improperPolynomial :: (Num a, Eq a, Integral a) => Int -> [a] -> [a]+improperPolynomial n poly = poly ++ replicate (fromIntegral n - length poly) 0++-- | Pads the given list with the requisite zeros to have a multiple of 8 length +padInt8 :: (Num a, Eq a, Integral a) => [a] -> [a]+padInt8 lst = lst ++ replicate ((8 - (length lst `mod` 8)) `mod` 8) 0 ++-- | Converts to octets+toOctets :: (Num a, Eq a, Integral a) => [a] -> [a]+toOctets lst = + let int2s = concatMap (reverse . take 2 . reverse . unpackByte 7) lst + in map (bitsToInt . padInt8) $ chunksOf 8 int2s+++{- Paramter Sets -}++-- | Generates the proper parameter set based on the given bit level+genParams :: (Num a, Eq a, Integral a) => a -> [Int]+genParams bit_level + | bit_level == 112 = [401,3,2048,113,133,1,112,60,600,400,113,1,113,11,32,0,0,2,4,114,112] + | bit_level == 128 = [449,3,2048,134,149,1,128,67,672,448,134,1,134,9,31,9,0,3,3,128,128]+ | bit_level == 192 = [677,3,2048,157,225,1,192,101,1008,676,157,256,157,11,27,9,0,5,3,192,192]+ | bit_level == 256 = [1087,3,2048,120,362,1,256,170,1624,1086,120,256,120,13,25,14,0,6,3,256,256]+ | otherwise = error "BitLevel must be 112, 128, 192, 256"++-- | Parsing functions for paramter set +getN = head+getP lst = fromIntegral $ lst!!1+getQ lst = fromIntegral $ lst!!2+getDf lst = lst!!3+getDg lst = lst!!4+getLLen lst = lst!!5+getDb lst = lst!!6+getMaxMsgLenBytes lst = lst!!7+getBufferLenBits lst = lst!!8+getBufferLenTrits lst = lst!!9+getDm0 lst = lst!!10+getSHA lst + | lst!!11 == 1 = sha1Octets+ | otherwise = sha256Octets +getHLen lst + | lst!!11 == 1 = 20 + | otherwise = 32 +getDr lst = lst!!12+getC lst = lst!!13+getMinCallsR lst = fromIntegral $ lst!!14+getMinCallsMask lst = fromIntegral $ lst!!15+getOID lst = [lst!!16,lst!!17,lst!!18]+getPkLen lst = lst!!19+getLvl lst = lst!!20+ +{- External Functions -}++-- | Generates a key-pair with the EES401EP1 Parameter Set+keyGen112 :: (Num a, Eq a, Integral a) => IO ([a], [a]) -- ^ A tuple representing (PublicKey, PrivateKey) where PrivateKey = 1 + pf, per Enhancement #2 at https://www.securityinnovation.com/uploads/Crypto/NTRU%20Enhancements%201.pdf+keyGen112 = generateKeyPair (genParams 112)++-- | Generates a key-pair with the EES449EP1 Parameter Set+keyGen128 :: (Num a, Eq a, Integral a) => IO ([a], [a])+keyGen128 = generateKeyPair (genParams 128)++-- | Generates a key-pair with the EES677EP1 Parameter Set+keyGen192 :: (Num a, Eq a, Integral a) => IO ([a], [a])+keyGen192 = generateKeyPair (genParams 192)++-- | Generates a key-pair with the EES1087EP2 Parameter Set+keyGen256 :: (Num a, Eq a, Integral a) => IO ([a], [a])+keyGen256 = generateKeyPair (genParams 256)++-- | Encrypts a message with the EES401EP1 Parameter Set +encrypt112 :: (Num a, Eq a, Integral a) => [a] -- ^ A list of ASCII values representing the message+ -> [a] -- ^ A list of numbers representing the public key+ -> IO [a] -- ^ A list of numbers representing the ciphertext+encrypt112 = encrypt (genParams 112)++-- | Encrypts a message with the EES449EP1 Parameter Set +encrypt128 :: (Num a, Eq a, Integral a) => [a] -> [a] -> IO [a]+encrypt128 = encrypt (genParams 128)++-- | Encrypts a message with the EES677EP1 Parameter Set +encrypt192 :: (Num a, Eq a, Integral a) => [a] -> [a] -> IO [a]+encrypt192 = encrypt (genParams 192)++-- | Encrypts a message with the EES1087EP2 Parameter Set+encrypt256 :: (Num a, Eq a, Integral a) => [a] -> [a] -> IO [a]+encrypt256 = encrypt (genParams 256)++-- | Decrypts and verifies a cyphertext with the EES401EP1 Parameter Set+decrypt112 :: (Num a, Eq a, Integral a) => [a] -- ^ A list of numbers representing the private key+ -> [a] -- ^ A list of numbers representing the public key+ -> [a] -- ^ A list of numbers representing the ciphertext+ -> [a] -- ^ A list of numbers representing the original message+decrypt112 = decrypt (genParams 112)++-- | Decrypts and verifies a cyphertext with the EES449EP1 Parameter Set+decrypt128 :: (Num a, Eq a, Integral a) => [a] -> [a] -> [a] -> [a]+decrypt128 = decrypt (genParams 128)++-- | Decrypts and verifies a cyphertext with the EES677EP1 Parameter Set+decrypt192 :: (Num a, Eq a, Integral a) => [a] -> [a] -> [a] -> [a]+decrypt192 = decrypt (genParams 192)++-- | Decrypts and verifies a cyphertext with the EES1087EP2 Parameter Set+decrypt256 :: (Num a, Eq a, Integral a) => [a] -> [a] -> [a] -> [a]+decrypt256 = decrypt (genParams 256)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain