270 lines
13 KiB
HTML
270 lines
13 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8"/>
|
||
|
<style>
|
||
|
table.head, table.foot { width: 100%; }
|
||
|
td.head-rtitle, td.foot-os { text-align: right; }
|
||
|
td.head-vol { text-align: center; }
|
||
|
div.Pp { margin: 1ex 0ex; }
|
||
|
</style>
|
||
|
<link rel="stylesheet" href="style.css" type="text/css" media="all"/>
|
||
|
<title>CRYPTO_SIGN_INIT_FIRST_PASS(3MONOCYPHER)</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<table class="head">
|
||
|
<tr>
|
||
|
<td class="head-ltitle">CRYPTO_SIGN_INIT_FIRST_PASS(3MONOCYPHER)</td>
|
||
|
<td class="head-vol">3MONOCYPHER</td>
|
||
|
<td class="head-rtitle">CRYPTO_SIGN_INIT_FIRST_PASS(3MONOCYPHER)</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<div class="manual-text">
|
||
|
<h1 class="Sh" title="Sh" id="NAME"><a class="selflink" href="#NAME">NAME</a></h1>
|
||
|
<b class="Nm" title="Nm">crypto_sign_init_first_pass</b>,
|
||
|
<b class="Nm" title="Nm">crypto_sign_update</b>,
|
||
|
<b class="Nm" title="Nm">crypto_sign_final</b>,
|
||
|
<b class="Nm" title="Nm">crypto_sign_init_second_pass</b>,
|
||
|
<b class="Nm" title="Nm">crypto_check_init</b>,
|
||
|
<b class="Nm" title="Nm">crypto_check_update</b>,
|
||
|
<b class="Nm" title="Nm">crypto_check_final</b> —
|
||
|
<span class="Nd" title="Nd">incremental public key signatures</span>
|
||
|
<h1 class="Sh" title="Sh" id="SYNOPSIS"><a class="selflink" href="#SYNOPSIS">SYNOPSIS</a></h1>
|
||
|
<b class="In" title="In">#include
|
||
|
<<a class="In" title="In">monocypher.h</a>></b>
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_first_pass</b>(<var class="Fa" title="Fa">crypto_sign_ctx
|
||
|
*ctx</var>, <var class="Fa" title="Fa">const uint8_t secret_key[32]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t public_key[32]</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>(<var class="Fa" title="Fa">crypto_sign_ctx
|
||
|
*ctx</var>, <var class="Fa" title="Fa">const uint8_t *message</var>,
|
||
|
<var class="Fa" title="Fa">size_t message_size</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_sign_final</b>(<var class="Fa" title="Fa">crypto_sign_ctx
|
||
|
*ctx</var>, <var class="Fa" title="Fa">uint8_t signature[64]</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_second_pass</b>(<var class="Fa" title="Fa">crypto_sign_ctx
|
||
|
*ctx</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_check_init</b>(<var class="Fa" title="Fa">crypto_check_ctx
|
||
|
*ctx</var>, <var class="Fa" title="Fa">const uint8_t signature[64]</var>,
|
||
|
<var class="Fa" title="Fa">const uint8_t public_key[32]</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">void</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_check_update</b>(<var class="Fa" title="Fa">crypto_check_ctx
|
||
|
*ctx</var>, <var class="Fa" title="Fa">const uint8_t *message</var>,
|
||
|
<var class="Fa" title="Fa">size_t message_size</var>);
|
||
|
<div class="Pp"></div>
|
||
|
<var class="Ft" title="Ft">int</var>
|
||
|
<br/>
|
||
|
<b class="Fn" title="Fn">crypto_check_final</b>(<var class="Fa" title="Fa">crypto_check_ctx
|
||
|
*ctx</var>);
|
||
|
<h1 class="Sh" title="Sh" id="DESCRIPTION"><a class="selflink" href="#DESCRIPTION">DESCRIPTION</a></h1>
|
||
|
These functions are variants of
|
||
|
<a class="Xr" title="Xr" href="crypto_sign.html">crypto_sign(3monocypher)</a>
|
||
|
and
|
||
|
<a class="Xr" title="Xr" href="crypto_check.html">crypto_check(3monocypher)</a>.
|
||
|
Prefer those simpler functions if possible.
|
||
|
<div class="Pp"></div>
|
||
|
The arguments are the same as those described in
|
||
|
<a class="Xr" title="Xr" href="crypto_sign.html">crypto_sign(3monocypher)</a>.
|
||
|
<div class="Pp"></div>
|
||
|
This incremental interface can be used to sign or verify messages too large to
|
||
|
fit in a single buffer. The arguments are the same as the direct interface
|
||
|
described in
|
||
|
<a class="Xr" title="Xr" href="crypto_sign.html">crypto_sign(3monocypher)</a>.
|
||
|
<div class="Pp"></div>
|
||
|
The direct and incremental interface produce and accept the same signatures.
|
||
|
<div class="Pp"></div>
|
||
|
Signing is done in two passes. This requires five steps:
|
||
|
<ul class="Bl-bullet">
|
||
|
<li class="It-bullet">Initialisation of the first pass with
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_first_pass</b>(). The public key
|
||
|
is optional, and will be recomputed if not provided. This recomputation
|
||
|
doubles the execution time for short messages.</li>
|
||
|
<li class="It-bullet">The first pass proper, with
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>().
|
||
|
<b class="Sy" title="Sy">Under no circumstances must you forget the first
|
||
|
pass</b>: Forgetting to call
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>() will appear to work in
|
||
|
that it produces valid signatures, but also loses all security because
|
||
|
attackers may now recover the secret key.</li>
|
||
|
<li class="It-bullet">Initialisation of the second pass with
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_second_pass</b>().</li>
|
||
|
<li class="It-bullet">The second pass proper, with
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>(). The same update
|
||
|
function is used for both passes.</li>
|
||
|
<li class="It-bullet">Signature generation with
|
||
|
<b class="Fn" title="Fn">crypto_sign_final</b>(). This also wipes the
|
||
|
context.</li>
|
||
|
</ul>
|
||
|
<div class="Pp"></div>
|
||
|
Verification requires three steps:
|
||
|
<ul class="Bl-bullet">
|
||
|
<li class="It-bullet">Initialisation with
|
||
|
<b class="Fn" title="Fn">crypto_check_init</b>().</li>
|
||
|
<li class="It-bullet">Update with
|
||
|
<b class="Fn" title="Fn">crypto_check_update</b>().</li>
|
||
|
<li class="It-bullet">Signature verification with
|
||
|
<b class="Fn" title="Fn">crypto_check_final</b>().</li>
|
||
|
</ul>
|
||
|
<h1 class="Sh" title="Sh" id="RETURN_VALUES"><a class="selflink" href="#RETURN_VALUES">RETURN
|
||
|
VALUES</a></h1>
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_first_pass</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_second_pass</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_final</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_check_init</b>() and
|
||
|
<b class="Fn" title="Fn">crypto_check_update</b>() return nothing.
|
||
|
<div class="Pp"></div>
|
||
|
<b class="Fn" title="Fn">crypto_check_final</b>() returns 0 for legitimate
|
||
|
messages and -1 for forgeries.
|
||
|
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
||
|
Sign a message:
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
uint8_t sk [ 32]; /* Secret key */
|
||
|
const uint8_t pk [ 32]; /* Public key (optional) */
|
||
|
const uint8_t message [500]; /* Message to sign */
|
||
|
uint8_t signature[ 64]; /* Output signature */
|
||
|
crypto_sign_ctx ctx;
|
||
|
crypto_sign_init_first_pass((crypto_sign_ctx_abstract*)&ctx, sk, pk);
|
||
|
/* Wipe the secret key if no longer needed */
|
||
|
crypto_wipe(sk, 32);
|
||
|
for (size_t i = 0; i < 500; i += 100) {
|
||
|
crypto_sign_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
|
||
|
}
|
||
|
crypto_sign_init_second_pass((crypto_sign_ctx_abstract*)&ctx);
|
||
|
for (size_t i = 0; i < 500; i += 100) {
|
||
|
crypto_sign_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
|
||
|
}
|
||
|
crypto_sign_final((crypto_sign_ctx_abstract*)&ctx, signature);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="Pp"></div>
|
||
|
Check the above:
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
const uint8_t pk [ 32]; /* Public key */
|
||
|
const uint8_t message [500]; /* Message to sign */
|
||
|
const uint8_t signature[ 64]; /* Signature to check */
|
||
|
crypto_check_ctx ctx;
|
||
|
crypto_check_init((crypto_sign_ctx_abstract*)&ctx, signature, pk);
|
||
|
for (size_t i = 0; i < 500; i += 100) {
|
||
|
crypto_check_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
|
||
|
}
|
||
|
if (crypto_check_final((crypto_sign_ctx_abstract*)&ctx)) {
|
||
|
/* Message is corrupted, abort processing */
|
||
|
} else {
|
||
|
/* Message is genuine */
|
||
|
}
|
||
|
</pre>
|
||
|
</div>
|
||
|
<div class="Pp"></div>
|
||
|
This interface can be used to mitigate attacks that leverage power analysis and
|
||
|
fault injection (glitching) – both of which require physical access and
|
||
|
appropriate equipment – by injecting additional randomness (at least 32
|
||
|
bytes) and padding (to the hash function's block size, which is 128 bytes for
|
||
|
all hash functions supported by Monocypher), of which 32 bytes are already
|
||
|
inserted into the buffer by
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_first_pass</b>(). Access to a
|
||
|
cryptographically secure pseudo-random generator is a requirement for
|
||
|
effective side channel mitigation. Signing a message with increased
|
||
|
power-related side channel mitigations:
|
||
|
<div class="Pp"></div>
|
||
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||
|
<pre class="Li">
|
||
|
const uint8_t message [ 500]; /* Message to sign */
|
||
|
uint8_t sk [ 32]; /* Secret key */
|
||
|
const uint8_t pk [ 32]; /* Public key (optional) */
|
||
|
uint8_t signature[ 64]; /* Output signature */
|
||
|
uint8_t buf [128-32] = {0}; /* Mitigation buffer */
|
||
|
crypto_sign_ctx ctx;
|
||
|
crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract *)&ctx;
|
||
|
|
||
|
arc4random_buf(buf, 32);
|
||
|
/* The rest of buf MUST be zeroes. */
|
||
|
|
||
|
crypto_sign_init_first_pass(actx, sk, pk);
|
||
|
crypto_sign_update (actx, buf, sizeof(buf));
|
||
|
crypto_sign_update (actx, message, 500);
|
||
|
|
||
|
crypto_sign_init_second_pass(actx);
|
||
|
crypto_sign_update (actx, message, 500);
|
||
|
crypto_sign_final (actx, signature);
|
||
|
|
||
|
crypto_wipe(buf, 32);
|
||
|
/* Wipe the secret key if no longer needed */
|
||
|
crypto_wipe(sk, 32);
|
||
|
</pre>
|
||
|
</div>
|
||
|
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
|
||
|
ALSO</a></h1>
|
||
|
<a class="Xr" title="Xr" href="crypto_blake2b.html">crypto_blake2b(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_key_exchange.html">crypto_key_exchange(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_lock.html">crypto_lock(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_sign.html">crypto_sign(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="crypto_wipe.html">crypto_wipe(3monocypher)</a>,
|
||
|
<a class="Xr" title="Xr" href="intro.html">intro(3monocypher)</a>
|
||
|
<h1 class="Sh" title="Sh" id="STANDARDS"><a class="selflink" href="#STANDARDS">STANDARDS</a></h1>
|
||
|
These functions implement PureEdDSA with Curve25519 and Blake2b, as described in
|
||
|
RFC 8032. This is the same as Ed25519, with Blake2b instead of SHA-512.
|
||
|
<div class="Pp"></div>
|
||
|
The example for side channel mitigation follows the methodology outlined in
|
||
|
I-D.draft-mattsson-cfrg-det-sigs-with-noise-02.
|
||
|
<h1 class="Sh" title="Sh" id="HISTORY"><a class="selflink" href="#HISTORY">HISTORY</a></h1>
|
||
|
The <b class="Fn" title="Fn">crypto_sign_init_first_pass</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_update</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_final</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_sign_init_second_pass</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_check_init</b>(),
|
||
|
<b class="Fn" title="Fn">crypto_check_update</b>(), and
|
||
|
<b class="Fn" title="Fn">crypto_check_final</b>() functions first appeared in
|
||
|
Monocypher 1.1.0.
|
||
|
<div class="Pp"></div>
|
||
|
<b class="Sy" title="Sy">A critical security vulnerability</b> that caused
|
||
|
all-zero signatures to be accepted was introduced in Monocypher 0.3; it was
|
||
|
fixed in Monocypher 1.1.1 and 2.0.4.
|
||
|
<h1 class="Sh" title="Sh" id="SECURITY_CONSIDERATIONS"><a class="selflink" href="#SECURITY_CONSIDERATIONS">SECURITY
|
||
|
CONSIDERATIONS</a></h1>
|
||
|
Messages are not verified until the call to
|
||
|
<b class="Fn" title="Fn">crypto_check_final</b>(). Messages may be stored
|
||
|
before they are verified, but they cannot be
|
||
|
<i class="Em" title="Em">trusted</i>. Processing untrusted messages increases
|
||
|
the attack surface of the system. Doing so securely is hard. Do not process
|
||
|
messages before calling <b class="Fn" title="Fn">crypto_check_final</b>().
|
||
|
<div class="Pp"></div>
|
||
|
When signing messages, the security considerations documented in
|
||
|
<a class="Xr" title="Xr" href="crypto_sign.html">crypto_sign(3monocypher)</a>
|
||
|
also apply. In particular, if power-related side channels are part of your
|
||
|
threat model, note that there may still be other power-related side channels
|
||
|
(such as if the CPU leaks information when an operation overflows a register)
|
||
|
that must be considered.
|
||
|
<h1 class="Sh" title="Sh" id="IMPLEMENTATION_DETAILS"><a class="selflink" href="#IMPLEMENTATION_DETAILS">IMPLEMENTATION
|
||
|
DETAILS</a></h1>
|
||
|
EdDSA signatures require two passes that cannot be performed in parallel. There
|
||
|
are ways around this limitation, but they all lower security in some way. For
|
||
|
this reason, Monocypher does not support them.</div>
|
||
|
<table class="foot">
|
||
|
<tr>
|
||
|
<td class="foot-date">March 31, 2020</td>
|
||
|
<td class="foot-os">Linux 4.15.0-106-generic</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</body>
|
||
|
</html>
|