Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision 81a0bf97e2012c369f800f26e2e3d3651cde7a35 authored by Matthias J. Kannwischer on 29 July 2021, 07:22:18 UTC, committed by Matthias J. Kannwischer on 02 August 2021, 03:06:46 UTC
Update NTRU Prime; add new round 3 parameter sets
1 parent 819f906
  • Files
  • Changes
  • b53fadd
  • /
  • crypto_sign
  • /
  • sphincs-haraka-256s-simple
  • /
  • clean
  • /
  • wots.c
Raw File Download
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • directory
  • content
revision badge
swh:1:rev:81a0bf97e2012c369f800f26e2e3d3651cde7a35
directory badge Iframe embedding
swh:1:dir:8692f19292aa587f333532a5fda82f56dd90c76d
content badge Iframe embedding
swh:1:cnt:912161dbee2217927123ffc704db9eef50d8311c
Citations

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • revision
  • directory
  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
wots.c
#include <stdint.h>
#include <string.h>

#include "address.h"
#include "hash.h"
#include "hash_state.h"
#include "params.h"
#include "thash.h"
#include "utils.h"
#include "wots.h"

// TODO clarify address expectations, and make them more uniform.
// TODO i.e. do we expect types to be set already?
// TODO and do we expect modifications or copies?

/**
 * Computes the starting value for a chain, i.e. the secret key.
 * Expects the address to be complete up to the chain address.
 */
static void wots_gen_sk(unsigned char *sk, const unsigned char *sk_seed,
                        uint32_t wots_addr[8],
                        const hash_state *hash_state_seeded) {
    /* Make sure that the hash address is actually zeroed. */
    PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_set_hash_addr(wots_addr, 0);

    /* Generate sk element. */
    PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_prf_addr(sk, sk_seed, wots_addr, hash_state_seeded);
}

/**
 * Computes the chaining function.
 * out and in have to be n-byte arrays.
 *
 * Interprets in as start-th value of the chain.
 * addr has to contain the address of the chain.
 */
static void gen_chain(unsigned char *out, const unsigned char *in,
                      unsigned int start, unsigned int steps,
                      const unsigned char *pub_seed, uint32_t addr[8],
                      const hash_state *hash_state_seeded) {
    uint32_t i;

    /* Initialize out with the value at position 'start'. */
    memcpy(out, in, PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N);

    /* Iterate 'steps' calls to the hash function. */
    for (i = start; i < (start + steps) && i < PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_W; i++) {
        PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_set_hash_addr(addr, i);
        PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_thash_1(
            out, out, pub_seed, addr, hash_state_seeded);
    }
}

/**
 * base_w algorithm as described in draft.
 * Interprets an array of bytes as integers in base w.
 * This only works when log_w is a divisor of 8.
 */
static void base_w(unsigned int *output, const size_t out_len,
                   const unsigned char *input) {
    size_t in = 0;
    size_t out = 0;
    unsigned char total = 0;
    unsigned int bits = 0;
    size_t consumed;

    for (consumed = 0; consumed < out_len; consumed++) {
        if (bits == 0) {
            total = input[in];
            in++;
            bits += 8;
        }
        bits -= PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LOGW;
        output[out] = (unsigned int)((total >> bits) & (PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_W - 1));
        out++;
    }
}

/* Computes the WOTS+ checksum over a message (in base_w). */
static void wots_checksum(unsigned int *csum_base_w,
                          const unsigned int *msg_base_w) {
    unsigned int csum = 0;
    unsigned char csum_bytes[(PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN2 * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LOGW + 7) / 8];
    unsigned int i;

    /* Compute checksum. */
    for (i = 0; i < PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN1; i++) {
        csum += PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_W - 1 - msg_base_w[i];
    }

    /* Convert checksum to base_w. */
    /* Make sure expected empty zero bits are the least significant bits. */
    csum = csum << (8 - ((PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN2 * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LOGW) % 8));
    PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_ull_to_bytes(
        csum_bytes, sizeof(csum_bytes), csum);
    base_w(csum_base_w, PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN2, csum_bytes);
}

/* Takes a message and derives the matching chain lengths. */
static void chain_lengths(unsigned int *lengths, const unsigned char *msg) {
    base_w(lengths, PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN1, msg);
    wots_checksum(lengths + PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN1, lengths);
}

/**
 * WOTS key generation. Takes a 32 byte sk_seed, expands it to WOTS private key
 * elements and computes the corresponding public key.
 * It requires the seed pub_seed (used to generate bitmasks and hash keys)
 * and the address of this WOTS key pair.
 *
 * Writes the computed public key to 'pk'.
 */
void PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_wots_gen_pk(
    unsigned char *pk, const unsigned char *sk_seed,
    const unsigned char *pub_seed, uint32_t addr[8],
    const hash_state *hash_state_seeded) {
    uint32_t i;

    for (i = 0; i < PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN; i++) {
        PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_set_chain_addr(addr, i);
        wots_gen_sk(pk + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, sk_seed, addr, hash_state_seeded);
        gen_chain(pk + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, pk + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N,
                  0, PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_W - 1, pub_seed, addr, hash_state_seeded);
    }
}

/**
 * Takes a n-byte message and the 32-byte sk_see to compute a signature 'sig'.
 */
void PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_wots_sign(
    unsigned char *sig, const unsigned char *msg,
    const unsigned char *sk_seed, const unsigned char *pub_seed,
    uint32_t addr[8], const hash_state *hash_state_seeded) {
    unsigned int lengths[PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN];
    uint32_t i;

    chain_lengths(lengths, msg);

    for (i = 0; i < PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN; i++) {
        PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_set_chain_addr(addr, i);
        wots_gen_sk(sig + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, sk_seed, addr, hash_state_seeded);
        gen_chain(sig + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, sig + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, 0, lengths[i], pub_seed, addr, hash_state_seeded);
    }
}

/**
 * Takes a WOTS signature and an n-byte message, computes a WOTS public key.
 *
 * Writes the computed public key to 'pk'.
 */
void PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_wots_pk_from_sig(
    unsigned char *pk,
    const unsigned char *sig, const unsigned char *msg,
    const unsigned char *pub_seed, uint32_t addr[8],
    const hash_state *hash_state_seeded) {
    unsigned int lengths[PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN];
    uint32_t i;

    chain_lengths(lengths, msg);

    for (i = 0; i < PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_LEN; i++) {
        PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_set_chain_addr(addr, i);
        gen_chain(pk + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N, sig + i * PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_N,
                  lengths[i], PQCLEAN_SPHINCSHARAKA256SSIMPLE_CLEAN_WOTS_W - 1 - lengths[i], pub_seed, addr,
                  hash_state_seeded);
    }
}
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Contact— JavaScript license information— Web API