.\" This file is dual-licensed.  Choose whichever you want.
.\"
.\" The first licence is a regular 2-clause BSD licence.  The second licence
.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
.\" to the public domain.  The BSD licence serves as a fallback option.
.\"
.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Copyright (c) 2019-2020 Fabio Scotoni
.\" All rights reserved.
.\"
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are
.\" met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\"
.\" 2. 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.
.\"
.\" 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
.\" HOLDER 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.
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Written in 2019-2020 by Fabio Scotoni
.\"
.\" To the extent possible under law, the author(s) have dedicated all copyright
.\" and related neighboring rights to this software to the public domain
.\" worldwide.  This software is distributed without any warranty.
.\"
.\" You should have received a copy of the CC0 Public Domain Dedication along
.\" with this software.  If not, see
.\" <https://creativecommons.org/publicdomain/zero/1.0/>
.\"
.Dd February 5, 2020
.Dt CRYPTO_SHA512 3MONOCYPHER
.Os
.Sh NAME
.Nm crypto_sha512 ,
.Nm crypto_sha512_init ,
.Nm crypto_sha512_update ,
.Nm crypto_sha512_final
.Nd cryptographic hashing with the SHA-512 algorithm
.Sh SYNOPSIS
.In monocypher-ed25519.h
.Ft void
.Fo crypto_sha512
.Fa "uint8_t hash[64]"
.Fa "const uint8_t *message"
.Fa "size_t message_size"
.Fc
.Ft void
.Fo crypto_sha512_init
.Fa "crypto_sha512_ctx *ctx"
.Fc
.Ft void
.Fo crypto_sha512_update
.Fa "crypto_sha512_ctx *ctx"
.Fa "const uint8_t *message"
.Fa "size_t message_size"
.Fc
.Ft void
.Fo crypto_sha512_final
.Fa "crypto_sha512_ctx *ctx"
.Fa "uint8_t hash[64]"
.Fc
.Sh DESCRIPTION
SHA-512 is a cryptographically secure hash,
provided to enable compatibility with other cryptographic systems.
It is generally recommended to use
.Xr crypto_blake2b 3monocypher
instead,
as it both performs faster on x86_64 CPUs and
lacks many of the pitfalls of SHA-512.
.Pp
Note that SHA-512 itself is not suitable for hashing passwords and
deriving keys from them;
use the
.Xr crypto_argon2i 3monocypher
family of functions for that purpose instead.
.Pp
SHA-512 is
.Em vulnerable to length extension attacks ;
using it as a message authentication code (MAC) algorithm or keyed hash
requires precautions.
The
.Xr crypto_hmac_sha512 3monocypher
family of functions provides HMAC with SHA-512.
Use
.Xr crypto_verify64 3monocypher
to compare MACs created this way.
.Pp
The arguments are:
.Bl -tag -width Ds
.It Fa hash
The output hash,
which is always 64 bytes long.
.It Fa message
The message to hash.
May overlap with
.Fa hash .
May be
.Dv NULL
if
.Fa message_size
is 0.
.It Fa message_size
Length of
.Fa message ,
in bytes.
.El
.Pp
An incremental interface is provided.
It is useful for handling streams of data or
large files without using too much memory.
This interface uses three steps:
.Bl -bullet
.It
initialisation with
.Fn crypto_sha512_init ,
which sets up a context with the hashing parameters;
.It
update with
.Fn crypto_sha512_update ,
which hashes the message chunk by chunk, and keep the intermediary
result in the context;
.It
and finalisation with
.Fn crypto_sha512_final ,
which produces the final hash.
The
.Ft crypto_sha512_ctx
is automatically wiped upon finalisation.
.El
.Pp
.Fn crypto_sha512
is a convenience function that
performs
.Fn crypto_sha512_init ,
.Fn crypto_sha512_update ,
and
.Fn crypto_sha512_final .
.Sh RETURN VALUES
These functions return nothing.
.Sh EXAMPLES
Hashing a message all at once:
.Bd -literal -offset indent
uint8_t hash   [64]; /* Output hash (64 bytes)          */
uint8_t message[12] = "Lorem ipsum"; /* Message to hash */
crypto_sha512(hash, message, 12);
.Ed
.Pp
Hashing a message incrementally:
.Bd -literal -offset indent
uint8_t hash   [ 64]; /* Output hash (64 bytes) */
uint8_t message[500] = {1}; /* Message to hash  */
crypto_sha512_ctx ctx;
crypto_sha512_init(&ctx);
for (size_t i = 0; i < 500; i += 100) {
    crypto_sha512_update(&ctx, message + i, 100);
}
crypto_sha512_final(&ctx, hash);
.Ed
.Sh SEE ALSO
.Xr crypto_blake2b 3monocypher ,
.Xr crypto_hmac_sha512 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr intro 3monocypher
.Sh STANDARDS
These functions implement SHA-512, described in RFC 6234 and
the Federal Information Processing Standard (FIPS) 180-4.
.Sh HISTORY
The
.Fn crypto_sha512 ,
.Fn crypto_sha512_init ,
.Fn crypto_sha512_update ,
and
.Fn crypto_sha512_final
functions first appeared in Monocypher 0.3;
they were not intended for use outside Monocypher itself and thus
undocumented.
They became part of the official API in Monocypher 3.0.0.
.Sh SECURITY CONSIDERATIONS
SHA-512 is a general-purpose cryptographic hash function;
this means that it is not suited for hashing passwords and deriving
cryptographic keys from passwords in particular.
While cryptographic keys usually have hundreds of bits of entropy,
passwords are often much less complex.
When storing passwords as hashes or when deriving keys from them,
the goal is normally to prevent attackers from quickly iterating all
possible passwords.
Because passwords tend to be simple,
it is important to artificially slow down attackers by using especially
computationally difficult hashing algorithms.
Monocypher therefore provides
.Xr crypto_argon2i 3monocypher
for password hashing and deriving keys from passwords.
