Raaz: A secure cryptographic library
The Raaz cryptographic library is a collection of Haskell packages whose goal is to provide high level access to cryptographic operations. The type system of Haskell plays a crucial role in avoiding some of common bugs in cryptographic implementations. The library is intended to be used for standalone cryptographic applications as well as implementing network protocols. Besides, we put a lot of emphasis on better API design and good documentation which, we believe, makes the usage of the library secure.
Some of the features that are unique to raaz are the following
- Pervasive use of types for better safety.
- Default choice of primitives and implementations are safe.
- Mechanism to have multiple implementations for any given cryptographic primitives. An advanced user who has an indepth knowledge of the platform should be able to plugin the desired implementation
- Strong emphasis on API design with through documentation.
Ensure that you have a ghc >= 8.2 and cabal version >= 2.2. These are necessary due to the crucial role played by backpack in the design. Having met these pre-requisites, the recommended approach towards building raaz using the following command.
Backpack support is still work in progress for stack and it should be possible to use stack once this issue is resolved.
Hacking and Discussion
For hacking see our github repository.
For discussion see our google groups mailing list.
Hangout on irc.freenode.net (channel: #haskell-raaz).
For details please refer to our wiki.
Releasing and reviewing.
The repository also contains the file Releasing.md which contains checklist for releasing a new version of the library. Any crypto library should undergo through review by multiple people. In the file Reviewing.md, we collect some common pitfalls to look for while reviewing the code. It is good to actively look for some of the problems suggested there but of course one should also look for other problems.
Backpack based pluggable implementations
NOTE: The interface that we describe now needs the ability for a
single package (
raaz in our case) to expose multiple
components. This is still work in progress but is expected to be
merged in soon (See
https://github.com/haskell/cabal/issues/4206). Without this feature
the interface described below cannot be used.
Certain cryptographic primitives can have better (both in terms of
safety and performance) implementations that exploit specific hardware
features. For example, if the underlying processor supports vector
avx2, some primitives like chacha20 can be made up
to 2x faster. Production quality cryptographic libraries are expected
to provide implementations tuned for such specific hardware. In
addition, it should be possible for users of esoteric platforms to
override the default implementation with their own custom
implementations. We use mixin-style modules provided by backpack to
achieve this goal.
The raaz cryptographic library is organised as a single package
containing multiple component. A user who only cares about the high
level interface can just ignore these individual components and use
only the top level library
raaz much like any other package. For
users who do care about changing the underlying implementation, having
an overall picture of these components is helpful.
raaz:corecontains core types and utility functions. You would most likely need this component to begin with.
raaz:indefexports a signature
Implementationand a module
Utilsthat depends on the signature. The
Implementationsignature captures the Haskell interface to the low level implementation of a cryptographic block primitive. To complement this indefinite package the component
raaz:implementationprovides implementations that can be "mixed-in" in place the signature
Implementation. A user can select one such implementation from
raaz:implementation, or can code up her own as long as it satisfies the
For each block primitive
foothat is supported by
raazthere is a component
raaz:foo-indef, that captures the various implementations of the primitive
foo. It reexports (a restricted version of) the signature
Implementationand the module
Foo.Utilsrespectively. For example,
raaz:chacha20-indefcomponent captures low-level implementations of the ChaCha20 stream cipher and exposes them as the signature
barthat wants to use a primitive
foowhile giving the flexibility for the downstream user to plugin different implementations of
fooshould define an indefinite package
bar:indef. The downstream user will then be able to
mixinthe appropriate implementation using the following in her cabal file
build-depends: raaz:chacha20-indef , bar:indef , raaz:implementation mixin: bar:indef (Bar as Bar.Portable) requires (ChaCha20.Implementations as ChaCha20.Portable) -- This makes use of the portable c implementation of -- ChaCha20 from raaz:implementation
For an example of this usage check out the component
and its use in the main library.
About the name
Raaz (राज़) stands for secret in Hindi.