packages feed

Dust-crypto-0.1: Dust/Crypto/ECDH.hs

module Dust.Crypto.ECDH
(
  splitSecret,
  createPrivate,
  createPublic,
  createKeypair,
  createShared,
  createEphemeral
) where

import Data.ByteString as B
import Data.Word
import Data.Bits
import Crypto.Threefish.Random

import Dust.Crypto.Keys
import Dust.Crypto.DustCipher
import Dust.Crypto.Curve25519

createEphemeral :: SkeinGen -> (Keypair, SkeinGen)
createEphemeral rand =
    let (bytes, rand') = randomBytes 32 rand
    in (createKeypair bytes, rand')

splitSecret :: ByteString -> (Word8,ByteString,Word8)
splitSecret bs = let firstByte = B.head bs
                     lastByte  = B.last bs
                     middle = B.tail (B.init bs)
                 in (firstByte,middle,lastByte)

createPrivate :: ByteString -> PrivateKey
createPrivate bs = let (firstByte,middle,lastByte) = splitSecret bs
                       firstByte' = firstByte .&. 248
                       lastByte'  = (lastByte .&. 127) .|. 64
                   in PrivateKey ((firstByte' `cons` middle) `snoc` lastByte')

createPublic :: PrivateKey -> PublicKey
createPublic private = let bps = pack [9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                       in PublicKey (curve25519 (privateBytes private) bps)

createKeypair :: ByteString -> Keypair
createKeypair entropy = let private = createPrivate entropy
                            public = createPublic private
                        in Keypair public private

createShared :: PrivateKey -> PublicKey -> EncryptionKey
createShared private public = EncryptionKey (curve25519 (privateBytes private) (publicBytes public))