packages feed

Dust 2.2.2 → 2.3.0

raw patch · 9 files changed

+6/−1201 lines, 9 filesdep +Dust-cryptodep +cryptohashdep +skeindep ~base

Dependencies added: Dust-crypto, cryptohash, skein

Dependency ranges changed: base

Files

Dust.cabal view
@@ -1,5 +1,5 @@ Name:                Dust-Version:             2.2.2+Version:             2.3.0 Description:         Dust is a polymorphic protocol engine designed to circumvent Internet filtering based on protocol identification Synopsis:            Polymorphic protocol engine Category:            Network@@ -12,7 +12,8 @@  Library   Build-Depends:-    base >= 3 && < 5,+    base >= 4.6.0.1 && < 5,+    Dust-crypto,     bytestring,     entropy,     network,@@ -26,17 +27,15 @@     containers,     directory,     split,+    skein,     crypto-api,+    cryptohash,     threefish   Extensions:     ForeignFunctionInterface    Exposed-modules:       Dust.Core.Invite,-      Dust.Crypto.Keys,-      Dust.Crypto.ECDSA,-      Dust.Crypto.ECDH,-      Dust.Crypto.DustCipher,       Dust.Model.PacketLength,       Dust.Model.Huffman,       Dust.Model.Content,@@ -49,23 +48,12 @@       Dust.Network.Util,       Dust.Network.ProtocolSocket ---  if os(windows)---    build-depends: Win32---    C-sources: lib/curve25519-donna.c, lib/ed25519-donna/ed25519.c---    extra-lib-dirs=C:\OpenSSL-Win64 /OpenSSL-Win64 C:\OpenSSL-Win64\lib C:\OpenSSL-Win64\bin---    extra-libraries: ssleay32 eay32-   if os(linux) || os(darwin)-    C-sources: lib/curve25519-donna.c, lib/ed25519-donna/ed25519.c-    Include-Dirs: lib-    extra-libraries: crypto     Exposed-modules:       Dust.Core.DustPacket       Dust.Core.CryptoProtocol       Dust.Core.WireProtocol       Dust.Core.WireProtocolHandler-      Dust.Crypto.Curve25519-      Dust.Crypto.Ed25519       Dust.Model.Port       Dust.Model.Packet       Dust.Network.DustServer@@ -99,6 +87,7 @@   build-depends:     base,     Dust,+    Dust-crypto,     HUnit >= 1.2,     test-framework       >= 0.6,     test-framework-hunit >= 0.2,
− Dust/Crypto/Curve25519.hs
@@ -1,39 +0,0 @@-{-# CFILES lib/curve25519-donna.c #-}-{-# LANGUAGE ForeignFunctionInterface #-}--module Dust.Crypto.Curve25519 (curve25519) where--import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import Data.ByteString.Unsafe (unsafeUseAsCString)-import Foreign.C.String (CString)--import Foreign.Marshal.Unsafe (unsafeLocalState)--curve25519 :: ByteString -> ByteString -> ByteString-curve25519 bs1 bs2 = curve-	where-	Just curve = unsafeLocalState $ unsafe_curve25519 bs1 bs2--unsafe_curve25519 :: ByteString -> ByteString -> IO (Maybe ByteString)-unsafe_curve25519 secret basepoint-    | B.length secret >= 32 && B.length basepoint >= 32 =-        -- This ByteString will be overwritten by the C call, but so long as-        -- the C side does not keep a reference to it afterward, it does what we-        -- expect and saves us a copy-        unsafeUseAsCString outBS $ \output ->-            B.useAsCString secret $ \csecret ->-                B.useAsCString basepoint $ \cbasepoint -> do-                    result <- c_curve25519_donna output csecret cbasepoint-                    case result of-                        0 -> return $ Just outBS-                        _ -> return Nothing-    | otherwise = return Nothing-    where-    outBS = B.replicate 32 0xAB---- Should be Ptr Word8 (not CString), but this should be safe if we just--- use them as bytes--foreign import ccall unsafe "curve25519_donna" c_curve25519_donna ::-    CString -> CString -> CString -> IO Int
− Dust/Crypto/DustCipher.hs
@@ -1,57 +0,0 @@-{-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get--module Dust.Crypto.DustCipher-(-  EncryptionKey(..),-  IV(..),-  Plaintext(..),-  Ciphertext(..),--  encrypt,-  decrypt,-  createIV-) where--import GHC.Generics-import Data.ByteString-import Data.Serialize-import Data.ByteString.Lazy (toChunks, fromChunks, toStrict)-import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as BL-import Crypto.Threefish-import Crypto.Threefish.Random-import qualified Crypto.Threefish.Skein.StreamCipher as SSC--import Dust.Crypto.Keys--data EncryptionKey = EncryptionKey ByteString deriving (Show, Eq)-newtype IV = IV ByteString deriving (Show, Eq, Generic)-newtype Plaintext = Plaintext ByteString deriving (Show, Eq, Generic)-newtype Ciphertext = Ciphertext ByteString deriving (Show, Eq, Generic)--instance Serialize IV-instance Serialize Plaintext-instance Serialize Ciphertext--encrypt :: EncryptionKey -> IV -> Plaintext -> Ciphertext-encrypt (EncryptionKey keyBytes) (IV ivBytes) (Plaintext plaintext) =-  let lazy = fromChunks [plaintext]-      maybeKey = toBlock keyBytes-      maybeIv = toBlock ivBytes-  in case (maybeKey, maybeIv) of-    (Just key, Just iv) -> Ciphertext $ toStrict $ SSC.encrypt key iv lazy-    otherwise           -> Ciphertext B.empty--decrypt :: EncryptionKey -> IV -> Ciphertext -> Plaintext-decrypt (EncryptionKey keyBytes) (IV ivBytes) (Ciphertext ciphertext) =-  let lazy = fromChunks [ciphertext]-      maybeKey = toBlock keyBytes-      maybeIv = toBlock ivBytes-  in case (maybeKey, maybeIv) of-    (Just key, Just iv) -> Plaintext $ toStrict $ SSC.decrypt key iv lazy-    otherwise           -> Plaintext B.empty--createIV :: SkeinGen -> (IV, SkeinGen)-createIV rand =-    let (ivBytes, rand') = randomBytes 32 rand-    in (IV ivBytes, rand')
− Dust/Crypto/ECDH.hs
@@ -1,47 +0,0 @@-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))
− Dust/Crypto/ECDSA.hs
@@ -1,42 +0,0 @@-{-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get--module Dust.Crypto.ECDSA-(-  Signature,-  Signedtext(..),-  createPrivate,-  createPublic,-  createSigningKeypair,-  sign,-  verify-) where--import GHC.Generics (Generic)-import Data.Serialize (Serialize)-import Data.ByteString (ByteString)--import Dust.Crypto.Keys-import Dust.Crypto.Ed25519--newtype Signature = Signature { signatureBytes :: ByteString } deriving (Show, Eq, Generic)-instance Serialize Signature--data Signedtext = Signedtext PublicKey Signature ByteString deriving (Eq, Show, Generic)-instance Serialize Signedtext--createPrivate :: ByteString -> PrivateKey-createPrivate = PrivateKey--createPublic :: PrivateKey -> PublicKey-createPublic = PublicKey . ed25519_publickey . privateBytes--createSigningKeypair :: ByteString -> Keypair-createSigningKeypair entropy = Keypair (createPublic private) private-    where-    private = createPrivate entropy--sign :: ByteString -> Keypair -> Signedtext-sign msg (Keypair pubkey private) = Signedtext pubkey (Signature $ ed25519_sign msg (privateBytes private) (publicBytes pubkey)) msg--verify :: Signedtext -> Bool-verify (Signedtext pubkey signature msg) = ed25519_sign_open msg (publicBytes pubkey) (signatureBytes signature)
− Dust/Crypto/Ed25519.hs
@@ -1,85 +0,0 @@-{-# CFILES lib/ed25519-donna/ed25519.c #-}-{-# LANGUAGE ForeignFunctionInterface #-}--module Dust.Crypto.Ed25519-(-    ed25519_publickey,-    ed25519_sign_open,-    ed25519_sign-) where--import qualified Data.ByteString as B-import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCString)--import Foreign.C-import Foreign.Marshal.Unsafe (unsafeLocalState)--ed25519_publickey :: ByteString -> ByteString-ed25519_publickey privkey = pubkey-    where-    Just pubkey = fmap unsafeLocalState (unsafe_ed25519_publickey privkey)--ed25519_sign_open :: ByteString -> ByteString -> ByteString -> Bool-ed25519_sign_open msg pubkey signature = result-	where-	Just result = fmap unsafeLocalState $ unsafe_ed25519_sign_open msg pubkey signature--ed25519_sign :: ByteString -> ByteString -> ByteString -> ByteString-ed25519_sign msg secret pubkey = signature-	where-	Just signature = fmap unsafeLocalState $ unsafe_ed25519_sign msg secret pubkey--unsafe_ed25519_publickey :: ByteString -> Maybe (IO ByteString)-unsafe_ed25519_publickey input-    | B.length input <= 32 = Just $-        -- This ByteString will be overwritten by the C call, but so long as-        -- the C side does not keep a reference to it afterward, it does what we-        -- expect and saves us a copy-        unsafeUseAsCString outBS $ \output ->-            B.useAsCString input $ \cinput -> do-                c_ed25519_publickey cinput output-                return outBS-    | otherwise = Nothing-    where-    outBS = B.replicate 32 0xAB-    {-# NOINLINE outBS #-}--unsafe_ed25519_sign_open :: ByteString -> ByteString -> ByteString -> Maybe (IO Bool)-unsafe_ed25519_sign_open msg pubkey signature-    | B.length pubkey <= 32 && B.length signature <= 64 = Just $-        B.useAsCStringLen msg $ \(cmsg, cmsglen) ->-            B.useAsCString pubkey $ \cpubkey ->-                B.useAsCString signature $ \csignature ->-                    let result = c_ed25519_sign_open cmsg (fromIntegral cmsglen) cpubkey csignature in-                        return (result == 0)-    | otherwise = Nothing--unsafe_ed25519_sign :: ByteString -> ByteString -> ByteString -> Maybe (IO ByteString)-unsafe_ed25519_sign msg secret pubkey-    | B.length secret <= 32 && B.length pubkey <= 32 = Just $-        -- This ByteString will be overwritten by the C call, but so long as-        -- the C side does not keep a reference to it afterward, it does what we-        -- expect and saves us a copy-        unsafeUseAsCString outBS $ \signature ->-            B.useAsCStringLen msg $ \(cmsg, cmsglen) ->-                B.useAsCString secret $ \csecret ->-                    B.useAsCString pubkey $ \cpubkey -> do-                        c_ed25519_sign cmsg (fromIntegral cmsglen) csecret cpubkey signature-                        return outBS-    | otherwise = Nothing-    where-    outBS = B.replicate 64 0xAB-    {-# NOINLINE outBS #-}---- Should be Ptr CUChar (not CString), but this should be safe if we just--- use them as bytes--foreign import ccall unsafe "ed25519_publickey" c_ed25519_publickey ::-   CString -> CString -> IO ()--foreign import ccall unsafe "ed25519_sign_open" c_ed25519_sign_open ::-    CString -> CSize -> CString -> CString -> CInt--foreign import ccall unsafe "ed25519_sign" c_ed25519_sign ::-    CString -> CSize -> CString -> CString -> CString -> IO ()
− Dust/Crypto/Keys.hs
@@ -1,75 +0,0 @@-{-# LANGUAGE DeriveGeneric, DefaultSignatures #-} -- For automatic generation of cereal put and get--module Dust.Crypto.Keys-(-   PublicKey(..),-   PrivateKey(..),-   Keypair(..),--   loadKeypair,-   saveKeypair,-   loadPublic,--   loadSigningKeypair,-   saveSigningKeypair-) where--import GHC.Generics-import Data.Serialize-import Data.ByteString--newtype PublicKey = PublicKey { publicBytes :: ByteString } deriving (Show, Eq, Generic)-newtype PrivateKey = PrivateKey { privateBytes :: ByteString } deriving (Show, Eq, Generic)--instance Serialize PublicKey--data Keypair = Keypair {-    public :: PublicKey,-    private :: PrivateKey-} deriving (Show, Eq)--loadKeypair :: IO (Keypair)-loadKeypair = do-    public <- loadPublic "id.pub"-    private <- loadPrivate "id.priv"-    return (Keypair public private)--loadPrivate :: FilePath -> IO (PrivateKey)-loadPrivate path = do-    key <- loadKey path-    return (PrivateKey key)--loadPublic :: FilePath -> IO (PublicKey)-loadPublic path = do-    key <- loadKey path-    return (PublicKey key)--loadKey :: FilePath -> IO (ByteString)-loadKey path = Data.ByteString.readFile path--saveKeypair :: Keypair -> IO ()-saveKeypair (Keypair public private) = do-    savePublic "id.pub" public-    savePrivate "id.priv" private--savePrivate :: FilePath -> PrivateKey -> IO ()-savePrivate path (PrivateKey bs) = do-    saveKey path bs--savePublic :: FilePath -> PublicKey -> IO ()-savePublic path (PublicKey bs) = do-    saveKey path bs--saveKey :: FilePath -> ByteString -> IO ()-saveKey path bs = Data.ByteString.writeFile path bs--loadSigningKeypair :: IO (Keypair)-loadSigningKeypair = do-    public <- loadPublic "sign.pub"-    private <- loadPrivate "sign.priv"-    return (Keypair public private)--saveSigningKeypair :: Keypair -> IO ()-saveSigningKeypair (Keypair public private) = do-    savePublic "sign.pub" public-    savePrivate "sign.priv" private
− lib/curve25519-donna.c
@@ -1,730 +0,0 @@-/* Copyright 2008, Google Inc.- * All rights reserved.- *- * Redistribution and use in source and binary forms, with or without- * modification, are permitted provided that the following conditions are- * met:- *- *     * Redistributions of source code must retain the above copyright- * notice, this list of conditions and the following disclaimer.- *     * Redistributions in binary form must reproduce the above- * copyright notice, this list of conditions and the following disclaimer- * in the documentation and/or other materials provided with the- * distribution.- *     * Neither the name of Google Inc. nor the names of its- * contributors may be used to endorse or promote products derived from- * this software without specific prior written permission.- *- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.- *- * curve25519-donna: Curve25519 elliptic curve, public key function- *- * http://code.google.com/p/curve25519-donna/- *- * Adam Langley <agl@imperialviolet.org>- *- * Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>- *- * More information about curve25519 can be found here- *   http://cr.yp.to/ecdh.html- *- * djb's sample implementation of curve25519 is written in a special assembly- * language called qhasm and uses the floating point registers.- *- * This is, almost, a clean room reimplementation from the curve25519 paper. It- * uses many of the tricks described therein. Only the crecip function is taken- * from the sample implementation.- */--#include <string.h>-#include <stdint.h>--typedef uint8_t u8;-typedef int32_t s32;-typedef int64_t limb;--/* Field element representation:- *- * Field elements are written as an array of signed, 64-bit limbs, least- * significant first. The value of the field element is:- *   x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...- *- * i.e. the limbs are 26, 25, 26, 25, ... bits wide.- */--/* Sum two numbers: output += in */-static void fsum(limb *output, const limb *in) {-  unsigned i;-  for (i = 0; i < 10; i += 2) {-    output[0+i] = (output[0+i] + in[0+i]);-    output[1+i] = (output[1+i] + in[1+i]);-  }-}--/* Find the difference of two numbers: output = in - output- * (note the order of the arguments!)- */-static void fdifference(limb *output, const limb *in) {-  unsigned i;-  for (i = 0; i < 10; ++i) {-    output[i] = (in[i] - output[i]);-  }-}--/* Multiply a number by a scalar: output = in * scalar */-static void fscalar_product(limb *output, const limb *in, const limb scalar) {-  unsigned i;-  for (i = 0; i < 10; ++i) {-    output[i] = in[i] * scalar;-  }-}--/* Multiply two numbers: output = in2 * in- *- * output must be distinct to both inputs. The inputs are reduced coefficient- * form, the output is not.- */-static void fproduct(limb *output, const limb *in2, const limb *in) {-  output[0] =       ((limb) ((s32) in2[0])) * ((s32) in[0]);-  output[1] =       ((limb) ((s32) in2[0])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[0]);-  output[2] =  2 *  ((limb) ((s32) in2[1])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[0]);-  output[3] =       ((limb) ((s32) in2[1])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[0]);-  output[4] =       ((limb) ((s32) in2[2])) * ((s32) in[2]) +-               2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[1])) +-                    ((limb) ((s32) in2[0])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[0]);-  output[5] =       ((limb) ((s32) in2[2])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[0]);-  output[6] =  2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[1])) +-                    ((limb) ((s32) in2[2])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[0]);-  output[7] =       ((limb) ((s32) in2[3])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[0]);-  output[8] =       ((limb) ((s32) in2[4])) * ((s32) in[4]) +-               2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[1])) +-                    ((limb) ((s32) in2[2])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[0]);-  output[9] =       ((limb) ((s32) in2[4])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[2]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[1]) +-                    ((limb) ((s32) in2[0])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[0]);-  output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[1])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[1])) +-                    ((limb) ((s32) in2[4])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[2]);-  output[11] =      ((limb) ((s32) in2[5])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[4]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[3]) +-                    ((limb) ((s32) in2[2])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[2]);-  output[12] =      ((limb) ((s32) in2[6])) * ((s32) in[6]) +-               2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[3])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[3])) +-                    ((limb) ((s32) in2[4])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[4]);-  output[13] =      ((limb) ((s32) in2[6])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[7])) * ((s32) in[6]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[5]) +-                    ((limb) ((s32) in2[4])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[4]);-  output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[5])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[5])) +-                    ((limb) ((s32) in2[6])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[6]);-  output[15] =      ((limb) ((s32) in2[7])) * ((s32) in[8]) +-                    ((limb) ((s32) in2[8])) * ((s32) in[7]) +-                    ((limb) ((s32) in2[6])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[6]);-  output[16] =      ((limb) ((s32) in2[8])) * ((s32) in[8]) +-               2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[7]));-  output[17] =      ((limb) ((s32) in2[8])) * ((s32) in[9]) +-                    ((limb) ((s32) in2[9])) * ((s32) in[8]);-  output[18] = 2 *  ((limb) ((s32) in2[9])) * ((s32) in[9]);-}--/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */-static void freduce_degree(limb *output) {-  /* Each of these shifts and adds ends up multiplying the value by 19. */-  output[8] += output[18] << 4;-  output[8] += output[18] << 1;-  output[8] += output[18];-  output[7] += output[17] << 4;-  output[7] += output[17] << 1;-  output[7] += output[17];-  output[6] += output[16] << 4;-  output[6] += output[16] << 1;-  output[6] += output[16];-  output[5] += output[15] << 4;-  output[5] += output[15] << 1;-  output[5] += output[15];-  output[4] += output[14] << 4;-  output[4] += output[14] << 1;-  output[4] += output[14];-  output[3] += output[13] << 4;-  output[3] += output[13] << 1;-  output[3] += output[13];-  output[2] += output[12] << 4;-  output[2] += output[12] << 1;-  output[2] += output[12];-  output[1] += output[11] << 4;-  output[1] += output[11] << 1;-  output[1] += output[11];-  output[0] += output[10] << 4;-  output[0] += output[10] << 1;-  output[0] += output[10];-}--#if (-1 & 3) != 3-#error "This code only works on a two's complement system"-#endif--/* return v / 2^26, using only shifts and adds. */-static inline limb-div_by_2_26(const limb v)-{-  /* High word of v; no shift needed*/-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);-  /* Set to all 1s if v was negative; else set to 0s. */-  const int32_t sign = ((int32_t) highword) >> 31;-  /* Set to 0x3ffffff if v was negative; else set to 0. */-  const int32_t roundoff = ((uint32_t) sign) >> 6;-  /* Should return v / (1<<26) */-  return (v + roundoff) >> 26;-}--/* return v / (2^25), using only shifts and adds. */-static inline limb-div_by_2_25(const limb v)-{-  /* High word of v; no shift needed*/-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);-  /* Set to all 1s if v was negative; else set to 0s. */-  const int32_t sign = ((int32_t) highword) >> 31;-  /* Set to 0x1ffffff if v was negative; else set to 0. */-  const int32_t roundoff = ((uint32_t) sign) >> 7;-  /* Should return v / (1<<25) */-  return (v + roundoff) >> 25;-}--static inline s32-div_s32_by_2_25(const s32 v)-{-   const s32 roundoff = ((uint32_t)(v >> 31)) >> 7;-   return (v + roundoff) >> 25;-}--/* Reduce all coefficients of the short form input so that |x| < 2^26.- *- * On entry: |output[i]| < 2^62- */-static void freduce_coefficients(limb *output) {-  unsigned i;--  output[10] = 0;--  for (i = 0; i < 10; i += 2) {-    limb over = div_by_2_26(output[i]);-    output[i] -= over << 26;-    output[i+1] += over;--    over = div_by_2_25(output[i+1]);-    output[i+1] -= over << 25;-    output[i+2] += over;-  }-  /* Now |output[10]| < 2 ^ 38 and all other coefficients are reduced. */-  output[0] += output[10] << 4;-  output[0] += output[10] << 1;-  output[0] += output[10];--  output[10] = 0;--  /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19 * 2^38-   * So |over| will be no more than 77825  */-  {-    limb over = div_by_2_26(output[0]);-    output[0] -= over << 26;-    output[1] += over;-  }--  /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 77825-   * So |over| will be no more than 1. */-  {-    /* output[1] fits in 32 bits, so we can use div_s32_by_2_25 here. */-    s32 over32 = div_s32_by_2_25((s32) output[1]);-    output[1] -= over32 << 25;-    output[2] += over32;-  }--  /* Finally, output[0,1,3..9] are reduced, and output[2] is "nearly reduced":-   * we have |output[2]| <= 2^26.  This is good enough for all of our math,-   * but it will require an extra freduce_coefficients before fcontract. */-}--/* A helpful wrapper around fproduct: output = in * in2.- *- * output must be distinct to both inputs. The output is reduced degree and- * reduced coefficient.- */-static void-fmul(limb *output, const limb *in, const limb *in2) {-  limb t[19];-  fproduct(t, in, in2);-  freduce_degree(t);-  freduce_coefficients(t);-  memcpy(output, t, sizeof(limb) * 10);-}--static void fsquare_inner(limb *output, const limb *in) {-  output[0] =       ((limb) ((s32) in[0])) * ((s32) in[0]);-  output[1] =  2 *  ((limb) ((s32) in[0])) * ((s32) in[1]);-  output[2] =  2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +-                    ((limb) ((s32) in[0])) * ((s32) in[2]));-  output[3] =  2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +-                    ((limb) ((s32) in[0])) * ((s32) in[3]));-  output[4] =       ((limb) ((s32) in[2])) * ((s32) in[2]) +-               4 *  ((limb) ((s32) in[1])) * ((s32) in[3]) +-               2 *  ((limb) ((s32) in[0])) * ((s32) in[4]);-  output[5] =  2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +-                    ((limb) ((s32) in[1])) * ((s32) in[4]) +-                    ((limb) ((s32) in[0])) * ((s32) in[5]));-  output[6] =  2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +-                    ((limb) ((s32) in[2])) * ((s32) in[4]) +-                    ((limb) ((s32) in[0])) * ((s32) in[6]) +-               2 *  ((limb) ((s32) in[1])) * ((s32) in[5]));-  output[7] =  2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +-                    ((limb) ((s32) in[2])) * ((s32) in[5]) +-                    ((limb) ((s32) in[1])) * ((s32) in[6]) +-                    ((limb) ((s32) in[0])) * ((s32) in[7]));-  output[8] =       ((limb) ((s32) in[4])) * ((s32) in[4]) +-               2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +-                    ((limb) ((s32) in[0])) * ((s32) in[8]) +-               2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +-                    ((limb) ((s32) in[3])) * ((s32) in[5])));-  output[9] =  2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +-                    ((limb) ((s32) in[3])) * ((s32) in[6]) +-                    ((limb) ((s32) in[2])) * ((s32) in[7]) +-                    ((limb) ((s32) in[1])) * ((s32) in[8]) +-                    ((limb) ((s32) in[0])) * ((s32) in[9]));-  output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +-                    ((limb) ((s32) in[4])) * ((s32) in[6]) +-                    ((limb) ((s32) in[2])) * ((s32) in[8]) +-               2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +-                    ((limb) ((s32) in[1])) * ((s32) in[9])));-  output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +-                    ((limb) ((s32) in[4])) * ((s32) in[7]) +-                    ((limb) ((s32) in[3])) * ((s32) in[8]) +-                    ((limb) ((s32) in[2])) * ((s32) in[9]));-  output[12] =      ((limb) ((s32) in[6])) * ((s32) in[6]) +-               2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +-               2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +-                    ((limb) ((s32) in[3])) * ((s32) in[9])));-  output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +-                    ((limb) ((s32) in[5])) * ((s32) in[8]) +-                    ((limb) ((s32) in[4])) * ((s32) in[9]));-  output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +-                    ((limb) ((s32) in[6])) * ((s32) in[8]) +-               2 *  ((limb) ((s32) in[5])) * ((s32) in[9]));-  output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +-                    ((limb) ((s32) in[6])) * ((s32) in[9]));-  output[16] =      ((limb) ((s32) in[8])) * ((s32) in[8]) +-               4 *  ((limb) ((s32) in[7])) * ((s32) in[9]);-  output[17] = 2 *  ((limb) ((s32) in[8])) * ((s32) in[9]);-  output[18] = 2 *  ((limb) ((s32) in[9])) * ((s32) in[9]);-}--static void-fsquare(limb *output, const limb *in) {-  limb t[19];-  fsquare_inner(t, in);-  freduce_degree(t);-  freduce_coefficients(t);-  memcpy(output, t, sizeof(limb) * 10);-}--/* Take a little-endian, 32-byte number and expand it into polynomial form */-static void-fexpand(limb *output, const u8 *input) {-#define F(n,start,shift,mask) \-  output[n] = ((((limb) input[start + 0]) | \-                ((limb) input[start + 1]) << 8 | \-                ((limb) input[start + 2]) << 16 | \-                ((limb) input[start + 3]) << 24) >> shift) & mask;-  F(0, 0, 0, 0x3ffffff);-  F(1, 3, 2, 0x1ffffff);-  F(2, 6, 3, 0x3ffffff);-  F(3, 9, 5, 0x1ffffff);-  F(4, 12, 6, 0x3ffffff);-  F(5, 16, 0, 0x1ffffff);-  F(6, 19, 1, 0x3ffffff);-  F(7, 22, 3, 0x1ffffff);-  F(8, 25, 4, 0x3ffffff);-  F(9, 28, 6, 0x1ffffff);-#undef F-}--#if (-32 >> 1) != -16-#error "This code only works when >> does sign-extension on negative numbers"-#endif--/* Take a fully reduced polynomial form number and contract it into a- * little-endian, 32-byte array- */-static void-fcontract(u8 *output, limb *input) {-  int i;-  int j;--  for (j = 0; j < 2; ++j) {-    for (i = 0; i < 9; ++i) {-      if ((i & 1) == 1) {-        /* This calculation is a time-invariant way to make input[i] positive-           by borrowing from the next-larger limb.-        */-        const s32 mask = (s32)(input[i]) >> 31;-        const s32 carry = -(((s32)(input[i]) & mask) >> 25);-        input[i] = (s32)(input[i]) + (carry << 25);-        input[i+1] = (s32)(input[i+1]) - carry;-      } else {-        const s32 mask = (s32)(input[i]) >> 31;-        const s32 carry = -(((s32)(input[i]) & mask) >> 26);-        input[i] = (s32)(input[i]) + (carry << 26);-        input[i+1] = (s32)(input[i+1]) - carry;-      }-    }-    {-      const s32 mask = (s32)(input[9]) >> 31;-      const s32 carry = -(((s32)(input[9]) & mask) >> 25);-      input[9] = (s32)(input[9]) + (carry << 25);-      input[0] = (s32)(input[0]) - (carry * 19);-    }-  }--  /* The first borrow-propagation pass above ended with every limb-     except (possibly) input[0] non-negative.--     Since each input limb except input[0] is decreased by at most 1-     by a borrow-propagation pass, the second borrow-propagation pass-     could only have wrapped around to decrease input[0] again if the-     first pass left input[0] negative *and* input[1] through input[9]-     were all zero.  In that case, input[1] is now 2^25 - 1, and this-     last borrow-propagation step will leave input[1] non-negative.-  */-  {-    const s32 mask = (s32)(input[0]) >> 31;-    const s32 carry = -(((s32)(input[0]) & mask) >> 26);-    input[0] = (s32)(input[0]) + (carry << 26);-    input[1] = (s32)(input[1]) - carry;-  }--  /* Both passes through the above loop, plus the last 0-to-1 step, are-     necessary: if input[9] is -1 and input[0] through input[8] are 0,-     negative values will remain in the array until the end.-   */--  input[1] <<= 2;-  input[2] <<= 3;-  input[3] <<= 5;-  input[4] <<= 6;-  input[6] <<= 1;-  input[7] <<= 3;-  input[8] <<= 4;-  input[9] <<= 6;-#define F(i, s) \-  output[s+0] |=  input[i] & 0xff; \-  output[s+1]  = (input[i] >> 8) & 0xff; \-  output[s+2]  = (input[i] >> 16) & 0xff; \-  output[s+3]  = (input[i] >> 24) & 0xff;-  output[0] = 0;-  output[16] = 0;-  F(0,0);-  F(1,3);-  F(2,6);-  F(3,9);-  F(4,12);-  F(5,16);-  F(6,19);-  F(7,22);-  F(8,25);-  F(9,28);-#undef F-}--/* Input: Q, Q', Q-Q'- * Output: 2Q, Q+Q'- *- *   x2 z3: long form- *   x3 z3: long form- *   x z: short form, destroyed- *   xprime zprime: short form, destroyed- *   qmqp: short form, preserved- */-static void fmonty(limb *x2, limb *z2,  /* output 2Q */-                   limb *x3, limb *z3,  /* output Q + Q' */-                   limb *x, limb *z,    /* input Q */-                   limb *xprime, limb *zprime,  /* input Q' */-                   const limb *qmqp /* input Q - Q' */) {-  limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],-        zzprime[19], zzzprime[19], xxxprime[19];--  memcpy(origx, x, 10 * sizeof(limb));-  fsum(x, z);-  fdifference(z, origx);  // does x - z--  memcpy(origxprime, xprime, sizeof(limb) * 10);-  fsum(xprime, zprime);-  fdifference(zprime, origxprime);-  fproduct(xxprime, xprime, z);-  fproduct(zzprime, x, zprime);-  freduce_degree(xxprime);-  freduce_coefficients(xxprime);-  freduce_degree(zzprime);-  freduce_coefficients(zzprime);-  memcpy(origxprime, xxprime, sizeof(limb) * 10);-  fsum(xxprime, zzprime);-  fdifference(zzprime, origxprime);-  fsquare(xxxprime, xxprime);-  fsquare(zzzprime, zzprime);-  fproduct(zzprime, zzzprime, qmqp);-  freduce_degree(zzprime);-  freduce_coefficients(zzprime);-  memcpy(x3, xxxprime, sizeof(limb) * 10);-  memcpy(z3, zzprime, sizeof(limb) * 10);--  fsquare(xx, x);-  fsquare(zz, z);-  fproduct(x2, xx, zz);-  freduce_degree(x2);-  freduce_coefficients(x2);-  fdifference(zz, xx);  // does zz = xx - zz-  memset(zzz + 10, 0, sizeof(limb) * 9);-  fscalar_product(zzz, zz, 121665);-  /* No need to call freduce_degree here:-     fscalar_product doesn't increase the degree of its input. */-  freduce_coefficients(zzz);-  fsum(zzz, xx);-  fproduct(z2, zz, zzz);-  freduce_degree(z2);-  freduce_coefficients(z2);-}--/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave- * them unchanged if 'iswap' is 0.  Runs in data-invariant time to avoid- * side-channel attacks.- *- * NOTE that this function requires that 'iswap' be 1 or 0; other values give- * wrong results.  Also, the two limb arrays must be in reduced-coefficient,- * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,- * and all all values in a[0..9],b[0..9] must have magnitude less than- * INT32_MAX.- */-static void-swap_conditional(limb a[19], limb b[19], limb iswap) {-  unsigned i;-  const s32 swap = (s32) -iswap;--  for (i = 0; i < 10; ++i) {-    const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );-    a[i] = ((s32)a[i]) ^ x;-    b[i] = ((s32)b[i]) ^ x;-  }-}--/* Calculates nQ where Q is the x-coordinate of a point on the curve- *- *   resultx/resultz: the x coordinate of the resulting curve point (short form)- *   n: a little endian, 32-byte number- *   q: a point of the curve (short form)- */-static void-cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {-  limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};-  limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;-  limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};-  limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;--  unsigned i, j;--  memcpy(nqpqx, q, sizeof(limb) * 10);--  for (i = 0; i < 32; ++i) {-    u8 byte = n[31 - i];-    for (j = 0; j < 8; ++j) {-      const limb bit = byte >> 7;--      swap_conditional(nqx, nqpqx, bit);-      swap_conditional(nqz, nqpqz, bit);-      fmonty(nqx2, nqz2,-             nqpqx2, nqpqz2,-             nqx, nqz,-             nqpqx, nqpqz,-             q);-      swap_conditional(nqx2, nqpqx2, bit);-      swap_conditional(nqz2, nqpqz2, bit);--      t = nqx;-      nqx = nqx2;-      nqx2 = t;-      t = nqz;-      nqz = nqz2;-      nqz2 = t;-      t = nqpqx;-      nqpqx = nqpqx2;-      nqpqx2 = t;-      t = nqpqz;-      nqpqz = nqpqz2;-      nqpqz2 = t;--      byte <<= 1;-    }-  }--  memcpy(resultx, nqx, sizeof(limb) * 10);-  memcpy(resultz, nqz, sizeof(limb) * 10);-}--// ------------------------------------------------------------------------------// Shamelessly copied from djb's code-// ------------------------------------------------------------------------------static void-crecip(limb *out, const limb *z) {-  limb z2[10];-  limb z9[10];-  limb z11[10];-  limb z2_5_0[10];-  limb z2_10_0[10];-  limb z2_20_0[10];-  limb z2_50_0[10];-  limb z2_100_0[10];-  limb t0[10];-  limb t1[10];-  int i;--  /* 2 */ fsquare(z2,z);-  /* 4 */ fsquare(t1,z2);-  /* 8 */ fsquare(t0,t1);-  /* 9 */ fmul(z9,t0,z);-  /* 11 */ fmul(z11,z9,z2);-  /* 22 */ fsquare(t0,z11);-  /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);--  /* 2^6 - 2^1 */ fsquare(t0,z2_5_0);-  /* 2^7 - 2^2 */ fsquare(t1,t0);-  /* 2^8 - 2^3 */ fsquare(t0,t1);-  /* 2^9 - 2^4 */ fsquare(t1,t0);-  /* 2^10 - 2^5 */ fsquare(t0,t1);-  /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);--  /* 2^11 - 2^1 */ fsquare(t0,z2_10_0);-  /* 2^12 - 2^2 */ fsquare(t1,t0);-  /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }-  /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);--  /* 2^21 - 2^1 */ fsquare(t0,z2_20_0);-  /* 2^22 - 2^2 */ fsquare(t1,t0);-  /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }-  /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);--  /* 2^41 - 2^1 */ fsquare(t1,t0);-  /* 2^42 - 2^2 */ fsquare(t0,t1);-  /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }-  /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);--  /* 2^51 - 2^1 */ fsquare(t0,z2_50_0);-  /* 2^52 - 2^2 */ fsquare(t1,t0);-  /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }-  /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);--  /* 2^101 - 2^1 */ fsquare(t1,z2_100_0);-  /* 2^102 - 2^2 */ fsquare(t0,t1);-  /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }-  /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);--  /* 2^201 - 2^1 */ fsquare(t0,t1);-  /* 2^202 - 2^2 */ fsquare(t1,t0);-  /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }-  /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);--  /* 2^251 - 2^1 */ fsquare(t1,t0);-  /* 2^252 - 2^2 */ fsquare(t0,t1);-  /* 2^253 - 2^3 */ fsquare(t1,t0);-  /* 2^254 - 2^4 */ fsquare(t0,t1);-  /* 2^255 - 2^5 */ fsquare(t1,t0);-  /* 2^255 - 21 */ fmul(out,t1,z11);-}--int curve25519_donna(u8 *, const u8 *, const u8 *);--int-curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {-  limb bp[10], x[10], z[11], zmone[10];-  uint8_t e[32];-  int i;--  for (i = 0; i < 32; ++i) e[i] = secret[i];-  e[0] &= 248;-  e[31] &= 127;-  e[31] |= 64;--  fexpand(bp, basepoint);-  cmult(x, z, e, bp);-  crecip(zmone, z);-  fmul(z, x, zmone);-  freduce_coefficients(z);-  fcontract(mypublic, z);-  return 0;-}
− lib/ed25519-donna/ed25519.c
@@ -1,109 +0,0 @@-/*-	Public domain by Andrew M. <liquidsun@gmail.com>--	Ed25519 reference implementation using Ed25519-donna-*/---#include "ed25519-donna.h"-#include "ed25519.h"-#include "ed25519-randombytes.h"-#include <openssl/sha.h>--/*-	Generates a (extsk[0..31]) and aExt (extsk[32..63])-*/--static void DONNA_INLINE-ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {-	SHA512(sk, 32, extsk);-	extsk[0] &= 248;-	extsk[31] &= 127;-	extsk[31] |= 64;-}--static void-ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {-	SHA512_CTX shactx;-	SHA512_Init(&shactx);-	SHA512_Update(&shactx, RS, 32);-	SHA512_Update(&shactx, pk, 32);-	SHA512_Update(&shactx, m, mlen);-	SHA512_Final(hram, &shactx);-}--void-ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk) {-	bignum256modm a;-	ge25519 MM16 A;-	hash_512bits extsk;--	/* A = aB */-	ed25519_extsk(extsk, sk);-	expand256_modm(a, extsk, 32);-	ge25519_scalarmult_base_niels(&A, a);-	ge25519_pack(pk, &A);-}---void-ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {-	SHA512_CTX shactx;-	bignum256modm r, S, a;-	ge25519 MM16 R;-	hash_512bits extsk, hashr, hram;--	ed25519_extsk(extsk, sk);--	/* r = H(aExt[32..64], m) */-	SHA512_Init(&shactx);-	SHA512_Update(&shactx, extsk + 32, 32);-	SHA512_Update(&shactx, m, mlen);-	SHA512_Final(hashr, &shactx);-	expand256_modm(r, hashr, 64);--	/* R = rB */-	ge25519_scalarmult_base_niels(&R, r);-	ge25519_pack(RS, &R);--	/* S = H(R,A,m).. */-	ed25519_hram(hram, RS, pk, m, mlen);-	expand256_modm(S, hram, 64);--	/* S = H(R,A,m)a */-	expand256_modm(a, extsk, 32);-	mul256_modm(S, S, a);--	/* S = (r + H(R,A,m)a) */-	add256_modm(S, S, r);--	/* S = (r + H(R,A,m)a) mod L */	-	contract256_modm(RS + 32, S);-}--int-ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {-	ge25519 MM16 R, A;-	hash_512bits hash;-	bignum256modm hram, S;-	unsigned char checkR[32];--	if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))-		return -1;--	/* hram = H(R,A,m) */-	ed25519_hram(hash, RS, pk, m, mlen);-	expand256_modm(hram, hash, 64);--	/* S */-	expand256_modm(S, RS + 32, 32);--	/* SB - H(R,A,m)A */-	ge25519_double_scalarmult_vartime(&R, &A, hram, S);-	ge25519_pack(checkR, &R);--	/* check that R = SB - H(R,A,m)A */-	return ed25519_verify(RS, checkR, 32) ? 0 : -1;-}--#include "ed25519-donna-batchverify.h"