summaryrefslogtreecommitdiff
path: root/Crypto/XEd25519
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-11-14 18:49:43 -0500
committerJoe Crayne <joe@jerkface.net>2019-11-14 18:49:43 -0500
commit6252bdbd0531feaa6ac9e881dffe5c92b8b40197 (patch)
treea36167c0739ee8c3bd4f36658ae1b3c8e0e6c333 /Crypto/XEd25519
parentb42c0d847a785487f3222b0d5360746d25d3209c (diff)
XEd25519 signature algorithm. (Signatures using montgomery cv25519 keys).
Diffstat (limited to 'Crypto/XEd25519')
-rw-r--r--Crypto/XEd25519/FieldElement.hs49
1 files changed, 49 insertions, 0 deletions
diff --git a/Crypto/XEd25519/FieldElement.hs b/Crypto/XEd25519/FieldElement.hs
new file mode 100644
index 0000000..7a91610
--- /dev/null
+++ b/Crypto/XEd25519/FieldElement.hs
@@ -0,0 +1,49 @@
1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE TypeOperators #-}
3module Crypto.XEd25519.FieldElement where
4
5import Crypto.Error
6import qualified Crypto.PubKey.Curve25519 as X25519
7import qualified Crypto.PubKey.Ed25519 as Ed25519
8import Data.ByteArray as BA (pack,unpack,Bytes)
9import Data.Modular
10import Data.Word
11
12-- 2^255 - 19
13type P25519 = 57896044618658097711785492504343953926634992332820282019728792003956564819949
14
15newtype FieldElement = FE (ℤ / P25519)
16
17
18fe_frombytes :: X25519.PublicKey -> FieldElement
19fe_frombytes pub = FE $ toMod $ decodeLittleEndian $ BA.unpack pub
20
21fe_tobytes :: FieldElement -> Ed25519.PublicKey
22fe_tobytes (FE x) = throwCryptoError $ Ed25519.publicKey (b :: Bytes)
23 where
24 b = BA.pack $ take 32 $ (encodeLittleEndian $ unMod x) ++ repeat 0
25
26fe_1 :: FieldElement
27fe_1 = FE $ toMod 1
28
29fe_sub :: FieldElement -> FieldElement -> FieldElement
30fe_sub (FE x) (FE y) = FE $ x - y
31
32fe_add :: FieldElement -> FieldElement -> FieldElement
33fe_add (FE x) (FE y) = FE $ x + y
34
35fe_invert :: FieldElement -> FieldElement
36fe_invert (FE x) = FE $ inv x
37
38fe_mul :: FieldElement -> FieldElement -> FieldElement
39fe_mul (FE x) (FE y) = FE (x * y)
40
41decodeLittleEndian :: [Word8] -> Integer
42decodeLittleEndian [] = 0
43decodeLittleEndian (x:xs) = fromIntegral x + 256 * decodeLittleEndian xs
44
45encodeLittleEndian :: Integer -> [Word8]
46encodeLittleEndian 0 = []
47encodeLittleEndian x = let (bs,b) = divMod x 256
48 in fromIntegral b : encodeLittleEndian bs
49