packages feed

crypton-2.1.3: cbits/tests/width/x25519_width.c

/* The same X25519 asked of the 32-bit donna and the 64-bit donna.  Both files
   define crypton_curve25519_donna, so they cannot share a binary: build twice
   and compare. */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

void crypton_curve25519_donna(uint8_t *mypublic, const uint8_t *secret,
                              const uint8_t *basepoint);

static uint64_t s0 = 0x243f6a8885a308d3ULL, s1 = 0x13198a2e03707344ULL;
static uint64_t rnd(void) {
    uint64_t x = s0, y = s1;
    s0 = y; x ^= x << 23;
    s1 = x ^ y ^ (x >> 17) ^ (y >> 26);
    return s1 + y;
}
static void show(const char *t, const uint8_t *b) {
    printf("%s ", t);
    for (int i = 0; i < 32; i++) printf("%02x", b[i]);
    printf("\n");
}

int main(void) {
    uint8_t sec[32], base[32], out[32];
    /* the named points: the generator, zero, one, the low-order points and
       the all-ones field element that reduces to nothing */
    static const uint8_t corners[][32] = {
        {9},
        {0},
        {1},
        {0xe0,0xeb,0x7a,0x7c,0x3b,0x41,0xb8,0xae,0x16,0x56,0xe3,0xfa,0xf1,0x9f,
         0xc4,0x6a,0xda,0x09,0x8d,0xeb,0x9c,0x32,0xb1,0xfd,0x86,0x62,0x05,0x16,
         0x5f,0x49,0xb8,0x00},
        {0x5f,0x9c,0x95,0xbc,0xa3,0x50,0x8c,0x24,0xb1,0xd0,0xb1,0x55,0x9c,0x83,
         0xef,0x5b,0x04,0x44,0x5c,0xc4,0x58,0x1c,0x8e,0x86,0xd8,0x22,0x4e,0xdd,
         0xd0,0x9f,0x11,0x57},
        {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
         0xff,0xff,0xff,0xff},
        {0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f},
    };
    for (unsigned c = 0; c < sizeof corners / sizeof *corners; c++) {
        memset(sec, 0, 32);
        sec[0] = (uint8_t)(0x40 + c); sec[31] = 0x40;
        crypton_curve25519_donna(out, sec, corners[c]);
        show("corner", out);
        /* and the scalars with every clamped bit at an edge */
        memset(sec, 0xff, 32); sec[0] = 0xf8; sec[31] = 0x7f;
        crypton_curve25519_donna(out, sec, corners[c]);
        show("cmax", out);
        memset(sec, 0x00, 32); sec[31] = 0x40;
        crypton_curve25519_donna(out, sec, corners[c]);
        show("cmin", out);
    }
    for (int it = 0; it < 2048; it++) {
        for (int i = 0; i < 32; i++) sec[i] = (uint8_t)(rnd() >> 24);
        for (int i = 0; i < 32; i++) base[i] = (uint8_t)(rnd() >> 24);
        crypton_curve25519_donna(out, sec, base);
        show("r", out);
        /* and a round trip: the shared secret both sides should agree on */
        uint8_t pa[32], pb[32], sa[32], sb[32], g[32] = {9};
        uint8_t s2[32];
        for (int i = 0; i < 32; i++) s2[i] = (uint8_t)(rnd() >> 24);
        crypton_curve25519_donna(pa, sec, g);
        crypton_curve25519_donna(pb, s2, g);
        crypton_curve25519_donna(sa, sec, pb);
        crypton_curve25519_donna(sb, s2, pa);
        printf("agree=%d\n", memcmp(sa, sb, 32) == 0);
        show("sa", sa);
    }
    return 0;
}