mirror of
https://github.com/logos-storage/transport-over-mix.git
synced 2026-05-19 19:39:35 +00:00
68 lines
1.4 KiB
Haskell
68 lines
1.4 KiB
Haskell
|
|
-- | The base field of Curve25519
|
|
|
|
module Crypto.X25519.BaseField where
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
import Data.Bits
|
|
import Data.Ratio
|
|
import System.Random
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
primeP :: Integer
|
|
primeP = 2^255 - 19
|
|
|
|
modP :: Integer -> Integer
|
|
modP x = mod x primeP
|
|
|
|
newtype Fp
|
|
= Fp Integer
|
|
deriving (Eq,Show)
|
|
|
|
fromFp :: Fp -> Integer
|
|
fromFp (Fp x) = x
|
|
|
|
toFp :: Integer -> Fp
|
|
toFp n = Fp (modP n)
|
|
|
|
instance Num Fp where
|
|
fromInteger = toFp
|
|
negate (Fp x) = toFp $ negate x
|
|
Fp x + Fp y = toFp $ x + y
|
|
Fp x - Fp y = toFp $ x - y
|
|
Fp x * Fp y = toFp $ x * y
|
|
abs x = x
|
|
signum _ = Fp 1
|
|
|
|
isZero :: Fp -> Bool
|
|
isZero (Fp x) = x == 0
|
|
|
|
pow :: Fp -> Integer -> Fp
|
|
pow base expo
|
|
| expo < 0 = pow (inv base) (negate expo)
|
|
| otherwise = go 1 base expo
|
|
where
|
|
go :: Fp -> Fp -> Integer -> Fp
|
|
go !acc !s 0 = acc
|
|
go !acc !s !e = case e .&. 1 of
|
|
0 -> go acc (s*s) (shiftR e 1)
|
|
1 -> go (acc*s) (s*s) (shiftR e 1)
|
|
|
|
inv :: Fp -> Fp
|
|
inv x = pow x (primeP - 2)
|
|
|
|
instance Fractional Fp where
|
|
fromRational r = toFp (numerator r) / toFp (denominator r)
|
|
recip = inv
|
|
x / y = x * inv y
|
|
|
|
randomFp :: IO Fp
|
|
randomFp = Fp <$> randomRIO (0,primeP-1)
|
|
|
|
randomFpNonZero :: IO Fp
|
|
randomFpNonZero = Fp <$> randomRIO (1,primeP-1)
|
|
|
|
--------------------------------------------------------------------------------
|