Esempio n. 1
0
/*
 * fieldset_deserialize
 *
 * Reconstitutes a field-set from a library.
 */
static int
fieldset_deserialize (void *vctx, name_t *np, void *fh,
                      unsigned int count)
{
    scopectx_t scope = parser_scope_get(expr_parse_ctx(vctx));
    namectx_t namectx = scope_namectx(scope);
    namereflist_t *frefs = name_extraspace(np);
    uint16_t n;
    size_t len;
    namedef_t ndef;
    char namebuf[NAME_SIZE];

    if (count != sizeof(n)) return 0;
    if (file_readbuf(fh, &n, count, &len) <= 0) return 0;
    if (len != count) return 0;
    if (n == 0) return 1;
    memset(&ndef, 0, sizeof(ndef));
    ndef.name = namebuf;
    while (n > 0) {
        name_t *fnp;
        unsigned int fcnt;
        if (!name_deserialize(fh, namebuf, &len, &ndef.lt, &ndef.flags, &fcnt)) return 0;
        if (ndef.lt != LEXTYPE_NAME_FIELD) return 0;
        ndef.namelen = len;
        fnp = name_declare(scope, &ndef, 0, 0, 0, 0);
        if (fnp == 0) return 0;
        if (!field_deserialize(vctx, fnp, fh, fcnt)) return 0;
        namereflist_instail(frefs, nameref_alloc(namectx, fnp));
        n -= 1;
    }
    return 1;

} /* fieldset_deserialize */
Esempio n. 2
0
int
goldilocks_verify (
    const uint8_t signature[GOLDI_SIGNATURE_BYTES],
    const uint8_t *message,
    uint64_t message_len,
    const struct goldilocks_public_key_t *pubkey
) {
    if (!goldilocks_check_init()) {
        return GOLDI_EUNINIT;
    }
    
    struct field_t pk;
    word_t s[GOLDI_FIELD_WORDS];
    
    mask_t succ = field_deserialize(&pk,pubkey->opaque);
    if (!succ) return GOLDI_EINVAL;
    
    succ = barrett_deserialize(s, &signature[GOLDI_FIELD_BYTES], &curve_prime_order);
    if (!succ) return GOLDI_EINVAL;
    
    word_t challenge[GOLDI_FIELD_WORDS];
    goldilocks_derive_challenge(challenge, pubkey->opaque, signature, message, message_len);
    
    struct field_t eph;
    struct tw_extensible_t pk_text;
    
    /* deserialize [nonce]G */
    succ = field_deserialize(&eph, signature);
    if (!succ) return GOLDI_EINVAL;
    
    succ = deserialize_and_twist_approx(&pk_text, &sqrt_d_minus_1, &pk);
    if (!succ) return GOLDI_EINVAL;
    
    linear_combo_var_fixed_vt( &pk_text,
        challenge, GOLDI_SCALAR_BITS,
        s, GOLDI_SCALAR_BITS,
        goldilocks_global.wnafs, WNAF_PRECMP_BITS );
    
    untwist_and_double_and_serialize( &pk, &pk_text );
    field_sub(&eph, &eph, &pk);
    field_bias(&eph, 2);
    
    succ = field_is_zero(&eph);
    
    return succ ? 0 : GOLDI_EINVAL;
}
Esempio n. 3
0
static mask_t mpz_to_field (
    field_a_t out,
    const mpz_t in
) {
    uint8_t ser[FIELD_BYTES];
    mpz_t modded;
    memset(ser,0,sizeof(ser));
    mpz_init(modded);
    mpz_mod(modded, in, mp_field);
    mpz_export(ser, NULL, -1, 1, -1, 0, modded);
    mask_t succ = field_deserialize(out, ser);
    return succ;
}
Esempio n. 4
0
int
goldilocks_private_to_public (
    struct goldilocks_public_key_t *pubkey,
    const struct goldilocks_private_key_t *privkey
) {
    struct field_t pk;
    mask_t msucc = field_deserialize(&pk,&privkey->opaque[GOLDI_FIELD_BYTES]);

    if (msucc) {
        field_serialize(pubkey->opaque, &pk);
        return GOLDI_EOK;
    } else {
        return GOLDI_ECORRUPT;
    }
}
Esempio n. 5
0
int
goldilocks_verify_precomputed (
    const uint8_t signature[GOLDI_SIGNATURE_BYTES],
    const uint8_t *message,
    uint64_t message_len,
    const struct goldilocks_precomputed_public_key_t *pubkey
) {
    if (!goldilocks_check_init()) {
        return GOLDI_EUNINIT;
    }

    word_t s[GOLDI_FIELD_WORDS];
    mask_t succ = barrett_deserialize(s, &signature[GOLDI_FIELD_BYTES], &curve_prime_order);
    if (!succ) return GOLDI_EINVAL;
    
    word_t challenge[GOLDI_FIELD_WORDS];
    goldilocks_derive_challenge(challenge, pubkey->pub.opaque, signature, message, message_len);
    
    struct field_t eph, pk;
    struct tw_extensible_t pk_text;
    
    /* deserialize [nonce]G */
    succ = field_deserialize(&eph, signature);
    if (!succ) return GOLDI_EINVAL;
        
    succ = linear_combo_combs_vt (
        &pk_text,
        challenge, GOLDI_SCALAR_BITS, &pubkey->table,
        s, GOLDI_SCALAR_BITS, &goldilocks_global.fixed_base
    );
    if (!succ) return GOLDI_EINVAL;
    
    untwist_and_double_and_serialize( &pk, &pk_text );
    field_sub(&eph, &eph, &pk);
    field_bias(&eph, 2);
    
    succ = field_is_zero(&eph);
    
    return succ ? 0 : GOLDI_EINVAL;
}
Esempio n. 6
0
struct goldilocks_precomputed_public_key_t *
goldilocks_precompute_public_key (
    const struct goldilocks_public_key_t *pub
) {
    struct goldilocks_precomputed_public_key_t *precom;
    precom = (struct goldilocks_precomputed_public_key_t *)
             malloc(sizeof(*precom));

    if (!precom) return NULL;

    struct tw_extensible_t pk_text;

    struct field_t pk;
    mask_t succ = field_deserialize(&pk, pub->opaque);
    if (!succ) {
        free(precom);
        return NULL;
    }

    succ = deserialize_and_twist_approx(&pk_text, &sqrt_d_minus_1, &pk);
    if (!succ) {
        free(precom);
        return NULL;
    }

    succ =  precompute_fixed_base(&precom->table, &pk_text,
                                  COMB_N, COMB_T, COMB_S, NULL);
    if (!succ) {
        free(precom);
        return NULL;
    }

    memcpy(&precom->pub,pub,sizeof(*pub));

    return precom;
}
Esempio n. 7
0
static int
goldilocks_shared_secret_core (
    uint8_t shared[GOLDI_SHARED_SECRET_BYTES],
    const struct goldilocks_private_key_t *my_privkey,
    const struct goldilocks_public_key_t *your_pubkey,
    const struct goldilocks_precomputed_public_key_t *pre
) {
    /* This function doesn't actually need anything in goldilocks_global,
     * so it doesn't check init.
     */

    assert(GOLDI_SHARED_SECRET_BYTES == SHA512_OUTPUT_BYTES);

    word_t sk[GOLDI_FIELD_WORDS];
    struct field_t pk;

    mask_t succ = field_deserialize(&pk,your_pubkey->opaque), msucc = -1;

#ifdef EXPERIMENT_ECDH_STIR_IN_PUBKEYS
    struct field_t sum, prod;
    msucc &= field_deserialize(&sum,&my_privkey->opaque[GOLDI_FIELD_BYTES]);
    field_mul(&prod,&pk,&sum);
    field_add(&sum,&pk,&sum);
#endif

    msucc &= barrett_deserialize(sk,my_privkey->opaque,&curve_prime_order);

#if GOLDI_IMPLEMENT_PRECOMPUTED_KEYS
    if (pre) {
        struct tw_extensible_t tw;
        succ &= scalarmul_fixed_base(&tw, sk, GOLDI_SCALAR_BITS, &pre->table);
        untwist_and_double_and_serialize(&pk, &tw);
    } else {
        succ &= montgomery_ladder(&pk,&pk,sk,GOLDI_SCALAR_BITS,1);
    }
#else
    (void)pre;
    succ &= montgomery_ladder(&pk,&pk,sk,GOLDI_SCALAR_BITS,1);
#endif


    field_serialize(shared,&pk);

    /* obliterate records of our failure by adjusting with obliteration key */
    struct sha512_ctx_t ctx;
    sha512_init(&ctx);

#ifdef EXPERIMENT_ECDH_OBLITERATE_CT
    uint8_t oblit[GOLDI_DIVERSIFY_BYTES + GOLDI_SYMKEY_BYTES];
    unsigned i;
    for (i=0; i<GOLDI_DIVERSIFY_BYTES; i++) {
        oblit[i] = "noshared"[i] & ~(succ&msucc);
    }
    for (i=0; i<GOLDI_SYMKEY_BYTES; i++) {
        oblit[GOLDI_DIVERSIFY_BYTES+i] = my_privkey->opaque[2*GOLDI_FIELD_BYTES+i] & ~(succ&msucc);
    }
    sha512_update(&ctx, oblit, sizeof(oblit));
#endif

#ifdef EXPERIMENT_ECDH_STIR_IN_PUBKEYS
    /* stir in the sum and product of the pubkeys. */
    uint8_t a_pk[GOLDI_FIELD_BYTES];
    field_serialize(a_pk, &sum);
    sha512_update(&ctx, a_pk, GOLDI_FIELD_BYTES);
    field_serialize(a_pk, &prod);
    sha512_update(&ctx, a_pk, GOLDI_FIELD_BYTES);
#endif

    /* stir in the shared key and finish */
    sha512_update(&ctx, shared, GOLDI_FIELD_BYTES);
    sha512_final(&ctx, shared);

    return (GOLDI_ECORRUPT & ~msucc)
           | (GOLDI_EINVAL & msucc &~ succ)
           | (GOLDI_EOK & msucc & succ);
}