Crate fn_dsa

Source
Expand description

§FN-DSA implementation

This crate is really a wrapper for the fn-dsa-kgen, fn-dsa-sign and fn-dsa-vrfy crates that implement the various elements of the FN-DSA signature algorithm. All the relevant types, functions and constants are re-exported here. Users of this implementation only need to import this crate; the division into sub-crates is meant to help with specialized situations where code footprint reduction is important (typically, embedded systems that only need to verify signatures, but not generate keys or signatures).

§WARNING

The FN-DSA standard is currently being drafted, but no version has been published yet. When published, it may differ from the exact scheme implemented in this crate, in particular with regard to key encodings, message pre-hashing, and domain separation. Key pairs generated with this crate MAY fail to be interoperable with the final FN-DSA standard. This implementation is expected to be adjusted to the FN-DSA standard when published (before the 1.0 version release).

§Implementation notes

The whole code is written in pure Rust and is compatible with no_std. It has no external dependencies except rand_core and zeroize (unit tests use a few extra crates).

On x86 (both 32-bit and 64-bit), AVX2 opcodes are automatically used for faster operations if their support is detected at runtime. No special compilation flag nor extra runtime check is needed for that; the compiled code remains compatible with plain non-AVX2-aware CPUs.

On 64-bit x86 (x86_64) and ARMv8 (aarch64, arm64ec), native (hardware) floating-point support is used, since in both these cases the architecture ABI mandates a strict IEEE-754 unit and can more or less be assumed to operate in constant-time for non-exceptional inputs. This makes signature generation much faster on these platforms (on x86_64, this furthermore combines with AVX2 optimizations if available in the current CPU). On other platforms, a portable emulation of floating-point operations is used (this emulation makes a best effort at operating in constant-time, though some recent compiler optimizations might introduce variable-time operations). Key pair generation and signature verification do not use floating-point operations at all.

The key pair generation implementation is a translation of the ntrugen code, which is faster than the originally submitted Falcon code. The signature generation engine follows the steps of the sign_dyn operations from the original falcon code (indeed, an internal unit tests checks that the sampler returns the same values for the same inputs). Achieved performance on x86_64 is very close to that offered by the C code (signature verification performance is even better).

§Example usage

use rand_core::OsRng;
use fn_dsa::{
    sign_key_size, vrfy_key_size, signature_size, FN_DSA_LOGN_512,
    KeyPairGenerator, KeyPairGeneratorStandard,
    SigningKey, SigningKeyStandard,
    VerifyingKey, VerifyingKeyStandard,
    DOMAIN_NONE, HASH_ID_RAW,
};
 
// Generate key pair.
let mut kg = KeyPairGeneratorStandard::default();
let mut sign_key = [0u8; sign_key_size(FN_DSA_LOGN_512)];
let mut vrfy_key = [0u8; vrfy_key_size(FN_DSA_LOGN_512)];
kg.keygen(FN_DSA_LOGN_512, &mut OsRng, &mut sign_key, &mut vrfy_key);
 
// Sign a message with the signing key.
let mut sk = SigningKeyStandard::decode(encoded_signing_key)?;
let mut sig = vec![0u8; signature_size(sk.get_logn())];
sk.sign(&mut OsRng, &DOMAIN_NONE, &HASH_ID_RAW, b"message", &mut sig);
 
// Verify a signature with the verifying key.
match VerifyingKeyStandard::decode(encoded_verifying_key) {
    Some(vk) => {
        if vk.verify(sig, &DOMAIN_NONE, &HASH_ID_RAW, b"message") {
            // signature is valid
        } else {
            // signature is not valid
        }
    }
    _ => {
        // could not decode verifying key
    }
}

Structs§

DomainContext
When a message is signed or verified, it is accompanied with a domain separation context, which is an arbitrary sequence of bytes of length at most 255. Such a context is wrapped in a DomainContext structure.
HashIdentifier
The message for which a signature is to be generated or verified is pre-hashed by the caller and provided as a hash value along with an identifier of the used hash function. The identifier is normally an encoded ASN.1 OID. A special identifier is used for “raw” messages (i.e. not pre-hashed at all); it uses a single byte of value 0x00.
KeyPairGenerator512
Key pair generator for degrees (logn) 9 to 9 only.
KeyPairGenerator1024
Key pair generator for degrees (logn) 10 to 10 only.
KeyPairGeneratorStandard
Key pair generator for degrees (logn) 9 to 10 only.
KeyPairGeneratorWeak
Key pair generator for degrees (logn) 2 to 8 only.
RngError
Error type of random number generators
SHA3_224
SHA3-224 implementation.
SHA3_256
SHA3-256 implementation.
SHA3_384
SHA3-384 implementation.
SHA3_512
SHA3-512 implementation.
SHAKE
SHAKE implementation.
SigningKey512
Signature generator for degrees (logn) 9 to 9 only.
SigningKey1024
Signature generator for degrees (logn) 10 to 10 only.
SigningKeyStandard
Signature generator for degrees (logn) 9 to 10 only.
SigningKeyWeak
Signature generator for degrees (logn) 2 to 8 only.
VerifyingKey512
Signature verifier for degrees (logn) 9 to 9 only.
VerifyingKey1024
Signature verifier for degrees (logn) 10 to 10 only.
VerifyingKeyStandard
Signature verifier for degrees (logn) 9 to 10 only.
VerifyingKeyWeak
Signature verifier for degrees (logn) 2 to 8 only.

Constants§

DOMAIN_NONE
Empty domain separation context.
FN_DSA_LOGN_512
Symbolic constant for FN-DSA with degree 512 (logn = 9).
FN_DSA_LOGN_1024
Symbolic constant for FN-DSA with degree 1024 (logn = 10).
HASH_ID_ORIGINAL_FALCON
Hash function identifier: original Falcon design.
HASH_ID_RAW
Hash function identifier: none.
HASH_ID_SHA3_256
Hash function identifier: SHA3-256
HASH_ID_SHA3_384
Hash function identifier: SHA3-384
HASH_ID_SHA3_512
Hash function identifier: SHA3-512
HASH_ID_SHA256
Hash function identifier: SHA-256
HASH_ID_SHA384
Hash function identifier: SHA-384
HASH_ID_SHA512
Hash function identifier: SHA-512
HASH_ID_SHA512_256
Hash function identifier: SHA-512-256
HASH_ID_SHAKE128
Hash function identifier: SHAKE128
HASH_ID_SHAKE256
Hash function identifier: SHAKE256

Traits§

CryptoRng
A marker trait used to indicate that an RngCore or BlockRngCore implementation is supposed to be cryptographically secure.
KeyPairGenerator
Key pair generator and temporary buffers.
RngCore
The core of a random number generator.
SigningKey
Signing key handler and temporary buffers.
VerifyingKey
Verifying key handler.

Functions§

sign_key_size
Get the size (in bytes) of a signing key for the provided degree (degree is n = 2^logn, with 2 <= logn <= 10).
signature_size
Get the size (in bytes) of a signature for the provided degree (degree is n = 2^logn, with 2 <= logn <= 10).
vrfy_key_size
Get the size (in bytes) of a verifying key for the provided degree (degree is n = 2^logn, with 2 <= logn <= 10).

Type Aliases§

SHAKE128
Type specialization for SHAKE128.
SHAKE256
Type specialization for SHAKE256.