{-| Module : Crypto.PastaCurves.PastaCurves Description : Provides the overall Pasta curve and field functionality. Copyright : (c) Eric Schorn, 2022 Maintainer : eric.schorn@nccgroup.com Stability : experimental Portability : GHC SPDX-License-Identifier: MIT This module provides the Pasta Curves consisting of: the `Pallas` curve and its `Fp` field element, the `Vesta` curve and its `Fq` field element, and a variety of supporting functionality such as point/element arithmetic, serialization, and hash-to-curve. The algorithms are NOT constant time; Safety and simplicity are the top priorities. \[ \text{Pallas: } y^2 = x^3 + 5 \text{ over } F_p(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) \] \[ \text{Vesta: } y^2 = x^3 + 5 \text{ over } F_q(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) \] The order of the Pallas curve is 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001. The order of the Vesta curve is 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001. The curves are designed such that the order of one matches the field characteristic of the other. For a brief introduction, see the Zcash blog titled "The Pasta Curves for Halo 2 and Beyond" at <https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/>. The reference Rust implementation (which inspired this implementation) can be found at: <https://github.com/zcash/pasta_curves>. Example usage of this library implementation: @ $ cabal repl ghci> a = 9 :: Fp ghci> a*a 0x0000000000000000000000000000000000000000000000000000000000000051 ghci> pointMul a base :: Vesta Projective {_px = 0x3CDC6A090F2BB3B52714C083929B620FE24ADBCBBD420752108CD7C29E543E5E, _py = 0x08795CD330B3CE5AA63BD2B18DE155AE3C96E8AF9DA2CC742C6BA1464E490161, _pz = 0x1FA26F58F3A641ADFE81775D3D53378D6178B6CCBF14F9BD4AB5F10DEE28D878} @ -} {-# LANGUAGE DataKinds, NoImplicitPrelude, Safe #-} module PastaCurves (Fp, Fq, Pallas, Vesta, CurvePt(..), Curve(..), hashToPallas, hashToVesta, rndPallas, rndVesta, Field(..), pallasPrime, vestaPrime, exampleFp, exampleFq, examplePallasPt, exampleVestaPt, Num(..)) where import Pasta (Fp, Fq, Num(..), Pallas, Vesta, CurvePt(..), Curve(..), Field(..), hashToPallas, hashToVesta, rndPallas, rndVesta, pallasPrime, vestaPrime) import Data.ByteString.UTF8 (fromString) -- | An example `Fp` element (8). exampleFp :: Fp exampleFp :: Fp exampleFp = Fp 8 -- | An example `Fq` element (999). exampleFq :: Fq exampleFq :: Fq exampleFq = Fq 999 -- | An example `Pallas` point generated by hashing a message. examplePallasPt :: Pallas examplePallasPt :: Pallas examplePallasPt = ByteString -> Pallas hashToPallas (String -> ByteString fromString String "A message to hash") -- | An example `Vesta` point (base * 8). exampleVestaPt :: Vesta exampleVestaPt :: Vesta exampleVestaPt = forall a b. Curve a b => b -> a -> a pointMul Fp exampleFp forall a. CurvePt a => a base