packages feed

crypton-2.2.2: cbits/tests/ct/ct_powm.c

/* The windowed modular exponentiation, which is what an RSA private key
 * operation runs.  The exponent is the secret it is built to hide. */
#include "tests/ct/ct.h"
#include <string.h>
#include "crypton_powm.h"

/* A 2048-bit modulus unless the build says otherwise: run.sh builds it at
 * the other sizes the vendored multiplication takes as well, since those
 * are different code. */
#ifndef CT_POWM_BYTES
#define CT_POWM_BYTES 256
#endif

#ifdef CT_POWM_COUNT_S2N
/* run.sh links this build with -Wl,--wrap=bignum_emontredc_8n, so every
 * reduction the s2n-bignum path does comes through here and is counted.
 * The build then says which implementation it ran, rather than leaving it
 * to be inferred: under valgrind the processor's answers are valgrind's,
 * and a build that quietly took the C would pass here while checking what
 * the plain powm build already has. */
#include <stdint.h>
uint64_t __real_bignum_emontredc_8n(uint64_t k, uint64_t *z,
                                    const uint64_t *m, uint64_t w);
static unsigned long s2n_reductions;
uint64_t __wrap_bignum_emontredc_8n(uint64_t k, uint64_t *z,
                                    const uint64_t *m, uint64_t w)
{
    s2n_reductions++;
    return __real_bignum_emontredc_8n(k, z, m, w);
}
#endif

int main(void) {
    enum { LEN = CT_POWM_BYTES };
    uint8_t out[LEN], base[LEN], mod[LEN], exp[LEN];

    ct_fill(base, sizeof base);
    ct_fill(mod, sizeof mod);
    ct_fill(exp, sizeof exp);
    mod[0] |= 0x80;                     /* full width */
    mod[LEN - 1] |= 1;                  /* and odd, which is what it wants */
    base[0] &= 0x7f;                    /* below the modulus */

    /* The exponent is the private key.  The base is the ciphertext, which an
     * attacker chooses and already knows, so it stays public. */
    CT_SECRET(exp, sizeof exp);

    if (crypton_powm_sec(out, base, LEN, exp, LEN, mod, LEN) != 0) {
        printf("powm_sec refused\n");
        return 1;
    }
    CT_PUBLIC(out, sizeof out);
    ct_sink(out, sizeof out);
#ifdef CT_POWM_COUNT_S2N
    printf("dispatch powm_s2n=%lu\n", s2n_reductions);
#endif
    return 0;
}