Crypt-Nettle

 view release on metacpan or  search on metacpan

Nettle.xs  view on Meta::CPAN

    Safefree(hexdata);
    return ret;
  }
  return _mpz_setSV(dst, src);
}

STATIC
SV *
_newSV_from_mpz(mpz_t src) {
    int sz;
    char* buf;
    SV * ret;
    int offset = 0;

    sz = mpz_sizeinbase(src, 16) + 4;
 /* add two bytes for leading '0x' plus one byte for minus sign (shouldn't ever be set?)
    and for the trailing NULL */
    ret = newSVpv("", sz);
    buf = (char*) SvPV_nolen(ret);
    mpz_get_str(buf + 2, 16, src);
    if (mpz_sgn(src) < 0) {
      offset = 1;
      buf[0] = '-';
    }
    buf[offset] = '0';
    buf[offset + 1] = 'x';
    SvCUR_set(ret, sz - (2 - offset)); /* get rid of the trailing NULL */
    return ret;
}

STATIC
SV *
_newSVraw_from_mpz(mpz_t src) {
    int sz;
    char* buf;
    char* retout;
    SV * ret;
    int offset = 0;
    struct base16_decode_ctx armor;
    unsigned retlen;

    if (mpz_sgn(src) < 0)
       croak("Expected a non-negative value here!");
    sz = mpz_sizeinbase(src, 16);
    if (sz % 2) {
       sz++;
       offset = 1;
    }
    Newxz(buf, sz, char);
    if (offset)
       buf[0] = '0';
    mpz_get_str(buf + offset, 16, src);

    retlen = sz/2;
    ret = newSVpv("", retlen);
    retout = SvPV_nolen(ret);
    base16_decode_init(&armor);
    if (0 == base16_decode_update(&armor, &retlen, retout, sz, buf))
       croak("Failed to decode mpz_t");
    if (retlen != sz/2)
       croak("size of decoded mpz_t was unexpected");
    if (0 == base16_decode_final(&armor))
       croak("Failed to finalize mpz_t decoding");
    Safefree(buf);

    return ret;
}


MODULE = Crypt::Nettle        PACKAGE = Crypt::Nettle::Hash    PREFIX = cnh_

Crypt_Nettle_Hash
cnh_new(classname, algoname)
    const char * classname;
    const char * algoname;
    PREINIT:
        Crypt_Nettle_Hash src;
        const struct nettle_hash* algo;
    CODE:
        if (0 != strcmp("Crypt::Nettle::Hash", classname))
           croak("Crypt::Nettle::Hash->new() was somehow called wrong");
        algo = _cnh_hash_lookup(algoname);
        if (NULL == algo) XSRETURN_UNDEF;
        Newxz(RETVAL, 1, struct Crypt_Nettle_Hash_s);
        if (NULL == RETVAL) XSRETURN_UNDEF;
        RETVAL->hashtype = algo;
        RETVAL->is_hmac = 0;
        Newx(RETVAL->hash_context, algo->context_size, char);
        if (NULL == RETVAL->hash_context) { Safefree(RETVAL); XSRETURN_UNDEF; };
        algo->init(RETVAL->hash_context);
    OUTPUT:
        RETVAL

Crypt_Nettle_Hash
cnh_new_hmac(classname, algoname, key)
    const char * classname;
    const char * algoname;
    SV* key;
    PREINIT:
        Crypt_Nettle_Hash src;
        const struct nettle_hash* algo;
        const uint8_t * keydata;
        int keylen;
    CODE:
        if (0 != strcmp("Crypt::Nettle::Hash", classname))
           croak("Crypt::Nettle::Hash->new_hmac() was somehow called wrong");
        keydata = SvPV(key, keylen);
        algo = _cnh_hash_lookup(algoname);
        if (NULL == algo) XSRETURN_UNDEF;
        Newxz(RETVAL, 1, struct Crypt_Nettle_Hash_s);
        if (NULL == RETVAL) XSRETURN_UNDEF;
        RETVAL->hashtype = algo;
        RETVAL->is_hmac = 1;
        Newx(RETVAL->hash_context, algo->context_size * 3, char); /* ??? will we run into alignment issues? */
        if (NULL == RETVAL->hash_context) { Safefree(RETVAL); XSRETURN_UNDEF; };
        hmac_set_key(RETVAL->hash_context + algo->context_size, 
                     RETVAL->hash_context + algo->context_size*2,
                     RETVAL->hash_context,
                     RETVAL->hashtype,
                     keylen, keydata
                     );



( run in 1.693 second using v1.01-cache-2.11-cpan-2398b32b56e )