void zzn2_out(_MIPD_ char *p,zzn2 *x) { printf(p); printf("\n"); redc(_MIPP_ x->a,x->a); redc(_MIPP_ x->b,x->b); otnum(_MIPP_ x->a,stdout); otnum(_MIPP_ x->b,stdout); nres(_MIPP_ x->a,x->a); nres(_MIPP_ x->b,x->b); }
BOOL zzn2_qr(_MIPD_ zzn2 *u) { int j; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; if (zzn2_iszero(u)) return TRUE; if (size(u->b)==0) return TRUE; if (mr_mip->qnr==-1 && size(u->a)==0) return TRUE; MR_IN(203) nres_modmult(_MIPP_ u->b,u->b,mr_mip->w1); if (mr_mip->qnr==-2) nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w1,mr_mip->w1); nres_modmult(_MIPP_ u->a,u->a,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); redc(_MIPP_ mr_mip->w1,mr_mip->w1); j=jack(_MIPP_ mr_mip->w1,mr_mip->modulus); MR_OUT if (j==1) return TRUE; return FALSE; }
BOOL zzn2_isunity(_MIPD_ zzn2 *x) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM || size(x->b)!=0) return FALSE; MR_IN(155) redc(_MIPP_ x->a,mr_mip->w1); MR_OUT if (size(mr_mip->w1)==1) return TRUE; return FALSE; }
void zzn3_inv(_MIPD_ zzn3 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(187) nres_modmult(_MIPP_ w->a,w->a,mr_mip->w1); nres_modmult(_MIPP_ w->b,w->c,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w2,mr_mip->cnr,mr_mip->w2); nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w3); nres_modmult(_MIPP_ w->c,w->c,mr_mip->w1); nres_modmult(_MIPP_ w->a,w->b,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w1,mr_mip->cnr,mr_mip->w1); nres_modsub(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w4); nres_negate(_MIPP_ mr_mip->w4,mr_mip->w4); nres_modmult(_MIPP_ w->b,w->b,mr_mip->w1); nres_modmult(_MIPP_ w->a,w->c,mr_mip->w2); nres_modsub(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5); nres_modmult(_MIPP_ w->b,mr_mip->w5,mr_mip->w1); nres_modmult(_MIPP_ w->c,mr_mip->w4,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w2,mr_mip->w1,mr_mip->w2); nres_premult(_MIPP_ mr_mip->w2,mr_mip->cnr,mr_mip->w2); nres_modmult(_MIPP_ w->a,mr_mip->w3,mr_mip->w1); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); copy(mr_mip->w3,w->a); copy(mr_mip->w4,w->b); copy(mr_mip->w5,w->c); redc(_MIPP_ mr_mip->w1,mr_mip->w6); invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); nres(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->a,mr_mip->w6,w->a); nres_modmult(_MIPP_ w->b,mr_mip->w6,w->b); nres_modmult(_MIPP_ w->c,mr_mip->w6,w->c); MR_OUT }
BOOL nres_sqroot(_MIPD_ big x,big w) { /* w=sqrt(x) mod p. This depends on p being prime! */ int t,js; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; copy(x,w); if (size(w)==0) return TRUE; MR_IN(100) redc(_MIPP_ w,w); /* get it back into normal form */ if (size(w)==1) /* square root of 1 is 1 */ { nres(_MIPP_ w,w); MR_OUT return TRUE; }
/* void zzn2_print(_MIPD_ char *label, zzn2 *x) { char s1[1024], s2[1024]; big a, b; #ifdef MR_STATIC char mem_big[MR_BIG_RESERVE(2)]; memset(mem_big, 0, MR_BIG_RESERVE(2)); a=mirvar_mem(_MIPP_ mem_big,0); b=mirvar_mem(_MIPP_ mem_big,1); #else a = mirvar(_MIPP_ 0); b = mirvar(_MIPP_ 0); #endif redc(_MIPP_ x->a, a); otstr(_MIPP_ a, s1); redc(_MIPP_ x->b, b); otstr(_MIPP_ b, s2); printf("%s: [%s,%s]\n", label, s1, s2); #ifndef MR_STATIC mr_free(a); mr_free(b); #endif } static void nres_print(_MIPD_ char *label, big x) { char s[1024]; big a; #ifdef MR_STATIC char mem_big[MR_BIG_RESERVE(1)]; memset(mem_big, 0, MR_BIG_RESERVE(1)); a=mirvar_mem(_MIPP_ mem_big,0); #else a = mirvar(_MIPP_ 0); #endif redc(_MIPP_ x, a); otstr(_MIPP_ a, s); printf("%s: %s\n", label, s); #ifndef MR_STATIC mr_free(a); #endif } */ void zzn2_inv(_MIPD_ zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(163) nres_modmult(_MIPP_ w->a,w->a,mr_mip->w1); nres_modmult(_MIPP_ w->b,w->b,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); if (mr_mip->qnr==-2) nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); redc(_MIPP_ mr_mip->w1,mr_mip->w6); invmodp(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6); nres(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->a,mr_mip->w6,w->a); nres_negate(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->b,mr_mip->w6,w->b); MR_OUT }
BOOL qnr(const ZZn& x) {redc(x.fn,get_mip()->w1); if (jack(get_mip()->w1,get_mip()->modulus)==-1) return TRUE; return FALSE;}
void gdk_pixbuf_blend ( GdkPixbuf* dst, const lib::rect dst_rc, GdkPixbuf* src, const lib::rect src_rc, double opacity_in, double opacity_out, const lib::color_t chroma_low, const lib::color_t chroma_high, const lib::color_t mask_color) { //TBD: dst(L,T,W,H) != src(L,T,W,H), alpha channel in dst/src assert(dst != NULL && src != NULL); guint n_channels_dst = gdk_pixbuf_get_n_channels (dst); guint n_channels_src = gdk_pixbuf_get_n_channels (src); assert (n_channels_dst >= 3 && n_channels_dst <= 4); // assert (n_channels_dst == n_channels_src); gint dst_L = dst_rc.x, dst_T = dst_rc.y; guint dst_W = dst_rc.w, dst_H = dst_rc.h; gint src_L = src_rc.x, src_T = src_rc.y; guint src_W = src_rc.w, src_H = src_rc.h; guchar* dst_col, * dst_row, * src_col, * src_row; gint col, row; gint L = dst_L <= src_L ? dst_L : src_L; gint T = dst_T <= src_T ? dst_T : src_T; guint W = dst_W <= src_W ? dst_W : src_W; guint H = dst_H <= src_H ? dst_H : src_H; guint R = L + W; guint B = T + H; guint weight_in = static_cast<guint>(round(opacity_in*255.0)); guint weight_out = static_cast<guint>(round(opacity_out*255.0)); guchar r_l = redc(chroma_low), r_h = redc(chroma_high), r_m = redc(mask_color); guchar g_l = greenc(chroma_low), g_h = greenc(chroma_high), g_m = greenc(mask_color); guchar b_l = bluec(chroma_low), b_h = bluec(chroma_high), b_m = bluec(mask_color); AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:r_l=%3d,g_l=%3d,b_l=%3d,w_in=%d,w_out=%d", r_l,g_l,b_l,weight_in, weight_out); AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:r_h=%3d,g_h=%3d,b_h=%3d", r_h,g_h,b_h); dst_row = gdk_pixbuf_get_pixels (dst); src_row = gdk_pixbuf_get_pixels (src); for (row = T; row < B; row++) { dst_col = dst_row; src_col = src_row; for (col = L; col < R; col++) { guchar r = src_col[0]; guchar g = src_col[1]; guchar b = src_col[2]; if ( ! (mask_color && r == r_m && g == g_m && b == b_m)) { guchar a = n_channels_src == 4 ? src_row[3] : 0xff; //AM_DBG logger::get_logger()->debug("blend_gdk_pixbuf:rc=(%3d,%3d),dst=(%3d,%3d,%3d),src=(%3d,%3d,%3d)",row,col,dst_col[0],dst_col[1],dst_col[2],r,g,b); // chromakeying if ( // check all components in chromakey range r_l <= r && r <= r_h && g_l <= g && g <= g_h && b_l <= b && b <= b_h ) { // blend the pixel from 'src' into 'dst' dst_col[0] = _blend_pixel(dst_col[0], r, weight_in); dst_col[1] = _blend_pixel(dst_col[1], g, weight_in); dst_col[2] = _blend_pixel(dst_col[2], b, weight_in); if (n_channels_dst == 4) dst_col[3] = _blend_pixel(dst_col[3], a, weight_in); } else { // blend the pixel from 'src' into 'dst' dst_col[0] = _blend_pixel(dst_col[0], r, weight_out); dst_col[1] = _blend_pixel(dst_col[1], g, weight_out); dst_col[2] = _blend_pixel(dst_col[2], b, weight_out); if (n_channels_dst == 4) dst_col[3] = _blend_pixel(dst_col[3], a, weight_out); } } dst_col += n_channels_dst; src_col += n_channels_src; } dst_row += gdk_pixbuf_get_rowstride(dst); src_row += gdk_pixbuf_get_rowstride(src); } }
/* For now, also disable REDC when MOD is even, as the inverse can't handle that. At some point, we might want to make the code faster for that case, perhaps using CRR. */ #ifndef POWM_THRESHOLD #define POWM_THRESHOLD ((8 * SQR_KARATSUBA_THRESHOLD) / 3) #endif #define HANDLE_NEGATIVE_EXPONENT 1 #undef REDUCE_EXPONENT void #ifndef BERKELEY_MP mpz_powm (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m) #else /* BERKELEY_MP */ pow (mpz_srcptr b, mpz_srcptr e, mpz_srcptr m, mpz_ptr r) #endif /* BERKELEY_MP */ { mp_ptr xp, tp, qp, gp, this_gp; mp_srcptr bp, ep, mp; mp_size_t bn, es, en, mn, xn; mp_limb_t invm, c; unsigned long int enb; mp_size_t i, K, j, l, k; int m_zero_cnt, e_zero_cnt; int sh; int use_redc; #if HANDLE_NEGATIVE_EXPONENT mpz_t new_b; #endif #if REDUCE_EXPONENT mpz_t new_e; #endif TMP_DECL (marker); mp = PTR(m); mn = ABSIZ (m); if (mn == 0) DIVIDE_BY_ZERO; TMP_MARK (marker); es = SIZ (e); if (es <= 0) { if (es == 0) { /* Exponent is zero, result is 1 mod m, i.e., 1 or 0 depending on if m equals 1. */ SIZ(r) = (mn == 1 && mp[0] == 1) ? 0 : 1; PTR(r)[0] = 1; TMP_FREE (marker); /* we haven't really allocated anything here */ return; } #if HANDLE_NEGATIVE_EXPONENT MPZ_TMP_INIT (new_b, mn + 1); if (! mpz_invert (new_b, b, m)) DIVIDE_BY_ZERO; b = new_b; es = -es; #else DIVIDE_BY_ZERO; #endif } en = es; #if REDUCE_EXPONENT /* Reduce exponent by dividing it by phi(m) when m small. */ if (mn == 1 && mp[0] < 0x7fffffffL && en * GMP_NUMB_BITS > 150) { MPZ_TMP_INIT (new_e, 2); mpz_mod_ui (new_e, e, phi (mp[0])); e = new_e; } #endif use_redc = mn < POWM_THRESHOLD && mp[0] % 2 != 0; if (use_redc) { /* invm = -1/m mod 2^BITS_PER_MP_LIMB, must have m odd */ modlimb_invert (invm, mp[0]); invm = -invm; } else { /* Normalize m (i.e. make its most significant bit set) as required by division functions below. */ count_leading_zeros (m_zero_cnt, mp[mn - 1]); m_zero_cnt -= GMP_NAIL_BITS; if (m_zero_cnt != 0) { mp_ptr new_mp; new_mp = TMP_ALLOC_LIMBS (mn); mpn_lshift (new_mp, mp, mn, m_zero_cnt); mp = new_mp; } } /* Determine optimal value of k, the number of exponent bits we look at at a time. */ count_leading_zeros (e_zero_cnt, PTR(e)[en - 1]); e_zero_cnt -= GMP_NAIL_BITS; enb = en * GMP_NUMB_BITS - e_zero_cnt; /* number of bits of exponent */ k = 1; K = 2; while (2 * enb > K * (2 + k * (3 + k))) { k++; K *= 2; } tp = TMP_ALLOC_LIMBS (2 * mn + 1); qp = TMP_ALLOC_LIMBS (mn + 1); gp = __GMP_ALLOCATE_FUNC_LIMBS (K / 2 * mn); /* Compute x*R^n where R=2^BITS_PER_MP_LIMB. */ bn = ABSIZ (b); bp = PTR(b); /* Handle |b| >= m by computing b mod m. FIXME: It is not strictly necessary for speed or correctness to do this when b and m have the same number of limbs, perhaps remove mpn_cmp call. */ if (bn > mn || (bn == mn && mpn_cmp (bp, mp, mn) >= 0)) { /* Reduce possibly huge base while moving it to gp[0]. Use a function call to reduce, since we don't want the quotient allocation to live until function return. */ if (use_redc) { reduce (tp + mn, bp, bn, mp, mn); /* b mod m */ MPN_ZERO (tp, mn); mpn_tdiv_qr (qp, gp, 0L, tp, 2 * mn, mp, mn); /* unnormnalized! */ } else { reduce (gp, bp, bn, mp, mn); } } else { /* |b| < m. We pad out operands to become mn limbs, which simplifies the rest of the function, but slows things down when the |b| << m. */ if (use_redc) { MPN_ZERO (tp, mn); MPN_COPY (tp + mn, bp, bn); MPN_ZERO (tp + mn + bn, mn - bn); mpn_tdiv_qr (qp, gp, 0L, tp, 2 * mn, mp, mn); } else { MPN_COPY (gp, bp, bn); MPN_ZERO (gp + bn, mn - bn); } } /* Compute xx^i for odd g < 2^i. */ xp = TMP_ALLOC_LIMBS (mn); mpn_sqr_n (tp, gp, mn); if (use_redc) redc (xp, mp, mn, invm, tp); /* xx = x^2*R^n */ else mpn_tdiv_qr (qp, xp, 0L, tp, 2 * mn, mp, mn); this_gp = gp; for (i = 1; i < K / 2; i++) { mpn_mul_n (tp, this_gp, xp, mn); this_gp += mn; if (use_redc) redc (this_gp, mp, mn, invm, tp); /* g[i] = x^(2i+1)*R^n */ else mpn_tdiv_qr (qp, this_gp, 0L, tp, 2 * mn, mp, mn); } /* Start the real stuff. */ ep = PTR (e); i = en - 1; /* current index */ c = ep[i]; /* current limb */ sh = GMP_NUMB_BITS - e_zero_cnt; /* significant bits in ep[i] */ sh -= k; /* index of lower bit of ep[i] to take into account */ if (sh < 0) { /* k-sh extra bits are needed */ if (i > 0) { i--; c <<= (-sh); sh += GMP_NUMB_BITS; c |= ep[i] >> sh; } }
int jacobi(const ZZn& x) {redc(x.fn,get_mip()->w1); return jack(get_mip()->w1,get_mip()->modulus); }