int main() { // Color Code char caRow[80]; int j = 7; int k = 2; int l = 5; int m = 1; while (true) { int i = 0; // Output a random row of characters while (i < 80) { if (caRow[i] != ' ') { caRow[i] = GetChar(j + i*i, 30, 33); //30, 33 } std::cout << caRow[i]; ++i; } j = (j + 31); k = (k + 17); l = (l + 47); m = (m + 67); caRow[Modulus(j, 80)] = '-'; caRow[Modulus(k, 80)] = ' '; caRow[Modulus(l, 80)] = '-'; caRow[Modulus(m, 80)] = ' '; // Delay i = 300000; while (i < 300000) { GetChar(1, 1, 1); ++i; } } return 0; }
double ThetaG(double epoch, deep_arg_t *deep_arg) { /* Reference: The 1992 Astronomical Almanac, page B6. */ double year,day,UT,jd,TU,GMST,ThetaG; /* Modification to support Y2K */ /* Valid 1957 through 2056 */ day = modf(epoch*1E-3,&year)*1E3; if(year < 57) year += 2000; else year += 1900; /* End modification */ UT = modf(day,&day); jd = Julian_Date_of_Year(year)+day; TU = (jd-2451545.0)/36525; GMST = 24110.54841+TU*(8640184.812866+TU*(0.093104-TU* 6.2E-6)); GMST = Modulus(GMST+secday*omega_E*UT,secday); ThetaG = twopi*GMST/secday; deep_arg->ds50 = jd-2433281.5+UT; ThetaG = FMod2p(6.3003880987*deep_arg->ds50+1.72944494); return (ThetaG); } /* Function ThetaG */
void Vector3::Normalize() { float mod = Modulus(); if (mod > 0.000001f) { *this /= mod; } }
Quaternion Quaternion::Inverse() { if (ModulusSqr() == 1.0) { return Conjugate(); } else { return Conjugate()/Modulus(); } }
void poly_eval_poly_polymod_coeffmod(const BigPoly &poly_to_evaluate, const BigPoly &poly_to_evaluate_at, const BigPoly &poly_modulus, const BigUInt &coeff_modulus, BigPoly &destination, const MemoryPoolHandle &pool) { if (!pool) { throw invalid_argument("pool is uninitialized"); } if (poly_to_evaluate.significant_coeff_count() > poly_modulus.coeff_count() || poly_to_evaluate.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate is not reduced"); } if (poly_to_evaluate_at.significant_coeff_count() > poly_modulus.coeff_count() || poly_to_evaluate_at.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate_at is not reduced"); } int poly_to_eval_coeff_uint64_count = poly_to_evaluate.coeff_uint64_count(); int coeff_modulus_bit_count = coeff_modulus.significant_bit_count(); if (poly_to_evaluate.is_zero()) { destination.set_zero(); } if (poly_to_evaluate_at.is_zero()) { destination.resize(1, coeff_modulus_bit_count); modulo_uint(poly_to_evaluate.data(), poly_to_eval_coeff_uint64_count, Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); return; } ConstPointer poly_to_eval_ptr = duplicate_poly_if_needed(poly_to_evaluate, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); ConstPointer poly_to_eval_at_ptr = duplicate_poly_if_needed(poly_to_evaluate_at, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); destination.resize(poly_modulus.coeff_count(), coeff_modulus_bit_count); util::poly_eval_poly_polymod_coeffmod(poly_to_eval_ptr.get(), poly_to_eval_at_ptr.get(), PolyModulus(poly_modulus.data(), poly_modulus.coeff_count(), poly_modulus.coeff_uint64_count()), Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); }
/* Calculates solar position vector */ void Calculate_Solar_Position(double _time, vector_t *solar_vector) { double mjd,year,T,M,L,e,C,O,Lsa,nu,R,eps; mjd = _time - 2415020.0; year = 1900 + mjd/365.25; T = (mjd + Delta_ET(year)/secday)/36525.0; M = Radians(Modulus(358.47583 + Modulus(35999.04975*T,360.0) - (0.000150 + 0.0000033*T)*Sqr(T),360.0)); L = Radians(Modulus(279.69668 + Modulus(36000.76892*T,360.0) + 0.0003025*Sqr(T),360.0)); e = 0.01675104 - (0.0000418 + 0.000000126*T)*T; C = Radians((1.919460 - (0.004789 + 0.000014*T)*T)*sin(M) + (0.020094 - 0.000100*T)*sin(2*M) + 0.000293*sin(3*M)); O = Radians(Modulus(259.18 - 1934.142*T,360.0)); Lsa = Modulus(L + C - Radians(0.00569 - 0.00479*sin(O)),twopi); nu = Modulus(M + C,twopi); R = 1.0000002*(1 - Sqr(e))/(1 + e*cos(nu)); eps = Radians(23.452294 - (0.0130125 + (0.00000164 - 0.000000503*T)*T)*T + 0.00256*cos(O)); R = AU*R; solar_vector->x = R*cos(Lsa); solar_vector->y = R*sin(Lsa)*cos(eps); solar_vector->z = R*sin(Lsa)*sin(eps); solar_vector->w = R; } /*Procedure Calculate_Solar_Position*/
Quaternion Quaternion::Normalize() { if (ModulusSqr() == 1.0) { return Quaternion(s, x, y, z); } else { float l = Modulus(); return Quaternion(s/l, x/l, y/l, z/l); } }
void Quaternion::NormalizeSelf() { if (ModulusSqr() != 1.0) { float l = Modulus(); s /= l; x /= l; y /= l; z /= l; } }
// Rabin-Miller method for finding a strong pseudo-prime // Preconditions: High bit and low bit of n = 1 bool RabinMillerPrimeTest( IRandom *prng, const u32 *n, // Number to check for primality int limbs, // Number of limbs in n u32 k) // Confidence level (40 is pretty good) { // n1 = n - 1 u32 *n1 = (u32 *)alloca(limbs*4); Set(n1, limbs, n); Subtract32(n1, limbs, 1); // d = n1 u32 *d = (u32 *)alloca(limbs*4); Set(d, limbs, n1); // remove factors of two from d while (!(d[0] & 1)) ShiftRight(limbs, d, d, 1); u32 *a = (u32 *)alloca(limbs*4); u32 *t = (u32 *)alloca(limbs*4); u32 *p = (u32 *)alloca((limbs*2)*4); u32 n_inv = MonReducePrecomp(n[0]); // iterate k times while (k--) { do prng->Generate(a, limbs*4); while (GreaterOrEqual(a, limbs, n, limbs)); // a = a ^ d (Mod n) ExpMod(a, limbs, d, limbs, n, limbs, n_inv, a); Set(t, limbs, d); while (!Equal(limbs, t, n1) && !Equal32(a, limbs, 1) && !Equal(limbs, a, n1)) { // TODO: verify this is actually working // a = a^2 (Mod n), non-critical path Square(limbs, p, a); Modulus(p, limbs*2, n, limbs, a); // t <<= 1 ShiftLeft(limbs, t, t, 1); } if (!Equal(limbs, a, n1) && !(t[0] & 1)) return false; } return true; }
void poly_eval_uint_mod(const BigPoly &poly_to_evaluate, const BigUInt &value, const BigUInt &modulus, BigUInt &destination, const MemoryPoolHandle &pool) { if (poly_to_evaluate.significant_coeff_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate is not reduced"); } if (value.significant_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("value is not reduced"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } int poly_to_eval_coeff_uint64_count = poly_to_evaluate.coeff_uint64_count(); int modulus_bit_count = modulus.significant_bit_count(); if (poly_to_evaluate.is_zero()) { destination.set_zero(); } if (value.is_zero()) { destination.resize(modulus_bit_count); modulo_uint(poly_to_evaluate.data(), poly_to_eval_coeff_uint64_count, Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); return; } ConstPointer value_ptr = duplicate_uint_if_needed(value, modulus.uint64_count(), false, pool); destination.resize(modulus_bit_count); util::poly_eval_uint_mod(poly_to_evaluate.data(), poly_to_evaluate.coeff_count(), value_ptr.get(), Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); }
double ThetaG_JD(double jd) { /* Reference: The 1992 Astronomical Almanac, page B6. */ double UT, TU, GMST; UT=Frac(jd+0.5); jd=jd-UT; TU=(jd-2451545.0)/36525; GMST=24110.54841+TU*(8640184.812866+TU*(0.093104-TU*6.2E-6)); GMST=Modulus(GMST+secday*omega_E*UT,secday); return (2*M_PI*GMST/secday); }
void exponentiate_poly_polymod_coeffmod(const BigPoly &operand, const BigUInt &exponent, const BigPoly &poly_modulus, const BigUInt &coeff_modulus, BigPoly &destination, const MemoryPoolHandle &pool) { if (operand.significant_coeff_count() > poly_modulus.coeff_count() || operand.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("operand is not reduced"); } if (exponent < 0) { throw invalid_argument("exponent must be a non-negative integer"); } if (operand.is_zero() && exponent == 0) { throw invalid_argument("undefined operation"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } if (operand.is_zero()) { destination.set_zero(); return; } if (destination.coeff_bit_count() != coeff_modulus.significant_bit_count() || destination.coeff_count() != poly_modulus.coeff_count()) { destination.resize(poly_modulus.coeff_count(), coeff_modulus.significant_bit_count()); } ConstPointer operand_ptr = duplicate_poly_if_needed(operand, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); util::exponentiate_poly_polymod_coeffmod(operand_ptr.get(), exponent.data(), exponent.uint64_count(), PolyModulus(poly_modulus.data(), poly_modulus.coeff_count(), poly_modulus.coeff_uint64_count()), Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); }
KeyGenerator::KeyGenerator(const EncryptionParameters &parms) : poly_modulus_(parms.poly_modulus()), coeff_modulus_(parms.coeff_modulus()), plain_modulus_(parms.plain_modulus()), noise_standard_deviation_(parms.noise_standard_deviation()), noise_max_deviation_(parms.noise_max_deviation()), decomposition_bit_count_(parms.decomposition_bit_count()), mode_(parms.mode()), random_generator_(parms.random_generator() != nullptr ? parms.random_generator()->create() : UniformRandomGeneratorFactory::default_factory()->create()) { // Verify required parameters are non-zero and non-nullptr. if (poly_modulus_.is_zero()) { throw invalid_argument("poly_modulus cannot be zero"); } if (coeff_modulus_.is_zero()) { throw invalid_argument("coeff_modulus cannot be zero"); } if (plain_modulus_.is_zero()) { throw invalid_argument("plain_modulus cannot be zero"); } if (noise_standard_deviation_ < 0) { throw invalid_argument("noise_standard_deviation must be non-negative"); } if (noise_max_deviation_ < 0) { throw invalid_argument("noise_max_deviation must be non-negative"); } if (decomposition_bit_count_ <= 0) { throw invalid_argument("decomposition_bit_count must be positive"); } // Verify parameters. if (plain_modulus_ >= coeff_modulus_) { throw invalid_argument("plain_modulus must be smaller than coeff_modulus"); } if (!are_poly_coefficients_less_than(poly_modulus_, coeff_modulus_)) { throw invalid_argument("poly_modulus cannot have coefficients larger than coeff_modulus"); } // Resize encryption parameters to consistent size. int coeff_count = poly_modulus_.significant_coeff_count(); int coeff_bit_count = coeff_modulus_.significant_bit_count(); int coeff_uint64_count = divide_round_up(coeff_bit_count, bits_per_uint64); if (poly_modulus_.coeff_count() != coeff_count || poly_modulus_.coeff_bit_count() != coeff_bit_count) { poly_modulus_.resize(coeff_count, coeff_bit_count); } if (coeff_modulus_.bit_count() != coeff_bit_count) { coeff_modulus_.resize(coeff_bit_count); } if (plain_modulus_.bit_count() != coeff_bit_count) { plain_modulus_.resize(coeff_bit_count); } if (decomposition_bit_count_ > coeff_bit_count) { decomposition_bit_count_ = coeff_bit_count; } // Calculate -1 (mod coeff_modulus). coeff_modulus_minus_one_.resize(coeff_bit_count); decrement_uint(coeff_modulus_.pointer(), coeff_uint64_count, coeff_modulus_minus_one_.pointer()); // Initialize public and secret key. public_key_.resize(coeff_count, coeff_bit_count); secret_key_.resize(coeff_count, coeff_bit_count); // Initialize evaluation keys. int evaluation_key_count = 0; Pointer evaluation_factor(allocate_uint(coeff_uint64_count, pool_)); set_uint(1, coeff_uint64_count, evaluation_factor.get()); while (!is_zero_uint(evaluation_factor.get(), coeff_uint64_count) && is_less_than_uint_uint(evaluation_factor.get(), coeff_modulus_.pointer(), coeff_uint64_count)) { left_shift_uint(evaluation_factor.get(), decomposition_bit_count_, coeff_uint64_count, evaluation_factor.get()); evaluation_key_count++; } evaluation_keys_.resize(evaluation_key_count); for (int i = 0; i < evaluation_key_count; ++i) { evaluation_keys_[i].resize(coeff_count, coeff_bit_count); } // Initialize moduli. polymod_ = PolyModulus(poly_modulus_.pointer(), coeff_count, coeff_uint64_count); mod_ = Modulus(coeff_modulus_.pointer(), coeff_uint64_count, pool_); }
/* Create the geometry - Create a surface - Turn it into an OpenGL list */ void MakeGeometry(void) { int i,j,k,niter=1; double r,r1,r2,r3,dp,scale,offset; double len,sealevel = 0; COLOUR colour; XYZ p,p1,p2,p3,n; /* Do this for new surfaces - zero the planet */ if (geometrydirty == REALDIRTY) { for (i=0;i<3;i++) { for (j=0;j<nface;j++) { Normalise(&(faces[j].p[i])); faces[j].c[i] = 0; } } niter = iterationdepth; srand(seedvalue); } printf( "Generating -S %i -F %i %s\n", seedvalue, spheredepth, (whichmethod == 1 ? "--origin" : "--notorigin")); if (geometrydirty == REALDIRTY || geometrydirty == ADDONE) { /* Form the new surface */ for (i=0;i<niter;i++) { /* Choose a random normal */ n.x = drand48() - 0.5; n.y = drand48() - 0.5; n.z = drand48() - 0.5; Normalise(&n); offset = drand48() - 0.5; /* Purturb the points dependng on which side they are on */ for (j=0;j<nface;j++) { for (k=0;k<3;k++) { if (whichmethod == 1) { p = faces[j].p[k]; } else { p.x = faces[j].p[k].x - offset * n.x; p.y = faces[j].p[k].y - offset * n.y; p.z = faces[j].p[k].z - offset * n.z; } if ((dp = DotProduct(n,p)) > 0) faces[j].c[k]++; else faces[j].c[k]--; } } } /* Adjust the heights */ for (j=0;j<nface;j++) { for (k=0;k<3;k++) { Normalise(&(faces[j].p[k])); scale = 1 + deltaheight * faces[j].c[k]; faces[j].p[k].x *= scale; faces[j].p[k].y *= scale; faces[j].p[k].z *= scale; } } } /* Find the range */ radiusmin = 1; radiusmax = 1; for (i=0;i<nface;i++) { for (k=0;k<3;k++) { r = Modulus(faces[i].p[k]); radiusmin = MIN(radiusmin,r); radiusmax = MAX(radiusmax,r); } } radiusmin -= deltaheight; radiusmax += deltaheight; if (debug) fprintf(stderr,"Radius range %g -> %g\n",radiusmin,radiusmax); /* Create the opengl data */ glNewList(1,GL_COMPILE); /* Draw the ocean sphere */ if (showocean) { sealevel = radiusmin + (radiusmax - radiusmin) / 2; glColor3f(0.4,0.4,1.0); CreateSimpleSphere(origin,sealevel-0.01,60,0); radiusmin = sealevel; } glBegin(GL_TRIANGLES); for (i=0;i<nface;i++) { p1 = faces[i].p[0]; r1 = Modulus(p1); p2 = faces[i].p[1]; r2 = Modulus(p2); p3 = faces[i].p[2]; r3 = Modulus(p3); if (r1 < sealevel && r2 < sealevel && r3 < sealevel) continue; colour = GetColour(r1,radiusmin,radiusmax,colourmap); glColor4f(colour.r,colour.g,colour.b,1.0); glNormal3f(p1.x,p1.y,p1.z); glVertex3f(p1.x,p1.y,p1.z); colour = GetColour(r2,radiusmin,radiusmax,colourmap); glColor4f(colour.r,colour.g,colour.b,1.0); glNormal3f(p2.x,p2.y,p2.z); glVertex3f(p2.x,p2.y,p2.z); colour = GetColour(r3,radiusmin,radiusmax,colourmap); glColor4f(colour.r,colour.g,colour.b,1.0); glNormal3f(p3.x,p3.y,p3.z); glVertex3f(p3.x,p3.y,p3.z); } glEnd(); glEndList(); }
// Function: calibrate // Purpose : Finds the A matrix(m_camera_matrix) and the m_distortion vector // from the loaded images. There must be at least 4 images in order to // get a correct A matrix. use more "different" images to get more // exact results. This function also calculates the respective // rotation and translation vectors for the input calibration // images. By using these information pixel error is calculated. // Output : m_camera_matrix: a0 = horizontal scaling, a4= vertical scaling, a1 = // skew (a2,a5) = principal point. // m_distortion: first two entries are radial m_distortion and last two // entries are tangential distoriton parameters. // ------------------------------------------------------------------------------ void camcal::CalibrateCamera() { if( m_effective_image_no == 0 ) return; int* numPoints = new int[m_effective_image_no]; int k; for( k=0; k < m_effective_image_no; k++ ) numPoints[k] = m_corner_no; delete[]m_distortion ; m_distortion = new double[4]; for( k=0; k<4; k++ ) m_distortion [k] = 0.0; delete[]m_camera_matrix ; m_camera_matrix = new double[9]; for( k=0; k<9; k++ ) m_camera_matrix[k] = 0.0; delete[]m_translation_vectors ; m_translation_vectors = new double[m_effective_image_no*3]; delete[]m_rotation_matrices ; m_rotation_matrices = new double[m_effective_image_no*9]; int useIntrinsicGuess = 0; CvPoint2D64d* uvinv = new CvPoint2D64d[m_effective_image_no * m_corner_no]; CvPoint3D64d* XYZinv = new CvPoint3D64d[m_effective_image_no * m_corner_no]; int index; for(int i=0 ; i<m_effective_image_no; i++) { for( int j=0; j<m_corner_no; j++ ) { index = Modulus( i+2, m_effective_image_no ); uvinv [i*m_corner_no+j].x = uveff [index*m_corner_no+j].x; uvinv [i*m_corner_no+j].y = uveff [index*m_corner_no+j].y; XYZinv[i*m_corner_no+j].x = XYZeff[index*m_corner_no+j].x; XYZinv[i*m_corner_no+j].y = XYZeff[index*m_corner_no+j].y; XYZinv[i*m_corner_no+j].z = XYZeff[index*m_corner_no+j].z; } } CvVect64d INVdistortion = new double[4]; CvMatr64d INVcameraMatrix = new double[9]; CvVect64d INVtransVects = new double[m_effective_image_no*3]; CvMatr64d INVrotMatrs = new double[m_effective_image_no*9]; // cvCalibrateCamera_64d SOMEHOW fails to find the first rotation matrix true. // However it gives correct results for the remaining images. Therefore, I invert all // the data sets and enter them in reverse order. By doing so, I will take the last // rotation matrix of the inverted data set as the rotation matrix of the normal // data set. cvCalibrateCamera_64d(m_effective_image_no, numPoints, imgsize, uveff, XYZeff, m_distortion, m_camera_matrix, m_translation_vectors, m_rotation_matrices, useIntrinsicGuess ); cvCalibrateCamera_64d(m_effective_image_no, numPoints, imgsize, uvinv, XYZinv, INVdistortion, INVcameraMatrix, INVtransVects, INVrotMatrs, useIntrinsicGuess ); CvVect64d focal = new double[2]; focal[0] = m_camera_matrix[0]; focal[1] = m_camera_matrix[4]; CvPoint2D64d principal; principal.x = m_camera_matrix[2]; principal.y = m_camera_matrix[5]; cvFindExtrinsicCameraParams_64d(m_corner_no, imgsize, uveff, XYZeff, focal, principal, m_distortion, m_rotation_matrices, m_translation_vectors ); cvFindExtrinsicCameraParams_64d(m_corner_no, imgsize, uvinv, XYZinv, focal, principal, INVdistortion, INVrotMatrs, INVtransVects ); // Correct first rotation matrix and translation vector! for( int i=0; i<9; i++ ) { index = Modulus(-2, m_effective_image_no ); m_rotation_matrices[i] = INVrotMatrs[index*9+i]; if( i<3 ) m_translation_vectors[i] = INVtransVects[3*index+i]; index = Modulus( m_effective_image_no-3, m_effective_image_no ); m_rotation_matrices[9*(m_effective_image_no-1)+i] = INVrotMatrs[index*9+i]; if( i<3 ) m_translation_vectors[3*(m_effective_image_no-1)+i] = INVtransVects[index*3+i]; } delete[]focal ; delete[]INVdistortion ; delete[]INVcameraMatrix; delete[]INVtransVects ; delete[]INVrotMatrs ; delete[]numPoints; delete []XYZinv; delete []uvinv; }
void exponentiate_uint_mod(const BigUInt &operand, const BigUInt &exponent, const BigUInt &modulus, BigUInt &destination, const MemoryPoolHandle &pool) { if (operand.significant_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("operand is not reduced"); } if (operand.is_zero() && exponent == 0) { throw invalid_argument("undefined operation"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } if (operand.is_zero()) { destination.set_zero(); return; } if (destination.bit_count() != modulus.significant_bit_count()) { destination.resize(modulus.significant_bit_count()); } ConstPointer operand_ptr = duplicate_uint_if_needed(operand, modulus.uint64_count(), false, pool); util::exponentiate_uint_mod(operand_ptr.get(), exponent.data(), exponent.uint64_count(), Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); }
HkeyGen::HkeyGen(const EncryptionParameters &parms, const BigPoly &secret_key) : poly_modulus_(parms.poly_modulus()), coeff_modulus_(parms.coeff_modulus()), plain_modulus_(parms.plain_modulus()), secret_key_(secret_key), orig_plain_modulus_bit_count_(parms.plain_modulus().significant_bit_count()) { // Verify required parameters are non-zero and non-nullptr. if (poly_modulus_.is_zero()) { throw invalid_argument("poly_modulus cannot be zero"); } if (coeff_modulus_.is_zero()) { throw invalid_argument("coeff_modulus cannot be zero"); } if (plain_modulus_.is_zero()) { throw invalid_argument("plain_modulus cannot be zero"); } if (secret_key_.is_zero()) { throw invalid_argument("secret_key cannot be zero"); } // Verify parameters. if (plain_modulus_ >= coeff_modulus_) { throw invalid_argument("plain_modulus must be smaller than coeff_modulus"); } if (!are_poly_coefficients_less_than(poly_modulus_, coeff_modulus_)) { throw invalid_argument("poly_modulus cannot have coefficients larger than coeff_modulus"); } // Resize encryption parameters to consistent size. int coeff_count = poly_modulus_.significant_coeff_count(); int coeff_bit_count = coeff_modulus_.significant_bit_count(); int coeff_uint64_count = divide_round_up(coeff_bit_count, bits_per_uint64); if (poly_modulus_.coeff_count() != coeff_count || poly_modulus_.coeff_bit_count() != coeff_bit_count) { poly_modulus_.resize(coeff_count, coeff_bit_count); } if (coeff_modulus_.bit_count() != coeff_bit_count) { coeff_modulus_.resize(coeff_bit_count); } if (plain_modulus_.bit_count() != coeff_bit_count) { plain_modulus_.resize(coeff_bit_count); } if (secret_key_.coeff_count() != coeff_count || secret_key_.coeff_bit_count() != coeff_bit_count || secret_key_.significant_coeff_count() == coeff_count || !are_poly_coefficients_less_than(secret_key_, coeff_modulus_)) { throw invalid_argument("secret_key is not valid for encryption parameters"); } // Set the secret_key_array to have size 1 (first power of secret) secret_key_array_.resize(1, coeff_count, coeff_bit_count); set_poly_poly(secret_key_.pointer(), coeff_count, coeff_uint64_count, secret_key_array_.pointer(0)); MemoryPool &pool = *MemoryPool::default_pool(); // Calculate coeff_modulus / plain_modulus. coeff_div_plain_modulus_.resize(coeff_bit_count); Pointer temp(allocate_uint(coeff_uint64_count, pool)); divide_uint_uint(coeff_modulus_.pointer(), plain_modulus_.pointer(), coeff_uint64_count, coeff_div_plain_modulus_.pointer(), temp.get(), pool); // Calculate coeff_modulus / plain_modulus / 2. coeff_div_plain_modulus_div_two_.resize(coeff_bit_count); right_shift_uint(coeff_div_plain_modulus_.pointer(), 1, coeff_uint64_count, coeff_div_plain_modulus_div_two_.pointer()); // Calculate coeff_modulus / 2. upper_half_threshold_.resize(coeff_bit_count); half_round_up_uint(coeff_modulus_.pointer(), coeff_uint64_count, upper_half_threshold_.pointer()); // Calculate upper_half_increment. upper_half_increment_.resize(coeff_bit_count); multiply_truncate_uint_uint(plain_modulus_.pointer(), coeff_div_plain_modulus_.pointer(), coeff_uint64_count, upper_half_increment_.pointer()); sub_uint_uint(coeff_modulus_.pointer(), upper_half_increment_.pointer(), coeff_uint64_count, upper_half_increment_.pointer()); // Initialize moduli. polymod_ = PolyModulus(poly_modulus_.pointer(), coeff_count, coeff_uint64_count); mod_ = Modulus(coeff_modulus_.pointer(), coeff_uint64_count, pool); }
inline bool Odd(const Type &a) { return (Modulus(a,Type(2))==Type(1)); }
char GetChar(int iGenerator, char cBase, int iRange) { return (cBase + Modulus(iGenerator, iRange)); }
Evaluator::Evaluator(const EncryptionParameters &parms, const EvaluationKeys &evaluation_keys) : poly_modulus_(parms.poly_modulus()), coeff_modulus_(parms.coeff_modulus()), plain_modulus_(parms.plain_modulus()), decomposition_bit_count_(parms.decomposition_bit_count()), evaluation_keys_(evaluation_keys), mode_(parms.mode()) { // Verify required parameters are non-zero and non-nullptr. if (poly_modulus_.is_zero()) { throw invalid_argument("poly_modulus cannot be zero"); } if (coeff_modulus_.is_zero()) { throw invalid_argument("coeff_modulus cannot be zero"); } if (plain_modulus_.is_zero()) { throw invalid_argument("plain_modulus cannot be zero"); } if (decomposition_bit_count_ <= 0) { throw invalid_argument("decomposition_bit_count must be positive"); } if (evaluation_keys_.count() == 0) { throw invalid_argument("evaluation_keys cannot be empty"); } // Verify parameters. if (plain_modulus_ >= coeff_modulus_) { throw invalid_argument("plain_modulus must be smaller than coeff_modulus"); } if (!are_poly_coefficients_less_than(poly_modulus_, coeff_modulus_)) { throw invalid_argument("poly_modulus cannot have coefficients larger than coeff_modulus"); } // Resize encryption parameters to consistent size. int coeff_count = poly_modulus_.significant_coeff_count(); int coeff_bit_count = coeff_modulus_.significant_bit_count(); int coeff_uint64_count = divide_round_up(coeff_bit_count, bits_per_uint64); if (poly_modulus_.coeff_count() != coeff_count || poly_modulus_.coeff_bit_count() != coeff_bit_count) { poly_modulus_.resize(coeff_count, coeff_bit_count); } if (coeff_modulus_.bit_count() != coeff_bit_count) { coeff_modulus_.resize(coeff_bit_count); } if (plain_modulus_.bit_count() != coeff_bit_count) { plain_modulus_.resize(coeff_bit_count); } if (decomposition_bit_count_ > coeff_bit_count) { decomposition_bit_count_ = coeff_bit_count; } // Determine correct number of evaluation keys. int evaluation_key_count = 0; Pointer evaluation_factor(allocate_uint(coeff_uint64_count, pool_)); set_uint(1, coeff_uint64_count, evaluation_factor.get()); while (!is_zero_uint(evaluation_factor.get(), coeff_uint64_count) && is_less_than_uint_uint(evaluation_factor.get(), coeff_modulus_.pointer(), coeff_uint64_count)) { left_shift_uint(evaluation_factor.get(), decomposition_bit_count_, coeff_uint64_count, evaluation_factor.get()); evaluation_key_count++; } // Verify evaluation keys. if (evaluation_keys_.count() != evaluation_key_count) { throw invalid_argument("evaluation_keys is not valid for encryption parameters"); } for (int i = 0; i < evaluation_keys_.count(); ++i) { BigPoly &evaluation_key = evaluation_keys_[i]; if (evaluation_key.coeff_count() != coeff_count || evaluation_key.coeff_bit_count() != coeff_bit_count || evaluation_key.significant_coeff_count() == coeff_count || !are_poly_coefficients_less_than(evaluation_key, coeff_modulus_)) { throw invalid_argument("evaluation_keys is not valid for encryption parameters"); } } // Calculate coeff_modulus / plain_modulus. coeff_div_plain_modulus_.resize(coeff_bit_count); Pointer temp(allocate_uint(coeff_uint64_count, pool_)); divide_uint_uint(coeff_modulus_.pointer(), plain_modulus_.pointer(), coeff_uint64_count, coeff_div_plain_modulus_.pointer(), temp.get(), pool_); // Calculate (plain_modulus + 1) / 2. plain_upper_half_threshold_.resize(coeff_bit_count); half_round_up_uint(plain_modulus_.pointer(), coeff_uint64_count, plain_upper_half_threshold_.pointer()); // Calculate coeff_modulus - plain_modulus. plain_upper_half_increment_.resize(coeff_bit_count); sub_uint_uint(coeff_modulus_.pointer(), plain_modulus_.pointer(), coeff_uint64_count, plain_upper_half_increment_.pointer()); // Calculate (plain_modulus + 1) / 2 * coeff_div_plain_modulus. upper_half_threshold_.resize(coeff_bit_count); multiply_truncate_uint_uint(plain_upper_half_threshold_.pointer(), coeff_div_plain_modulus_.pointer(), coeff_uint64_count, upper_half_threshold_.pointer()); // Calculate upper_half_increment. upper_half_increment_.resize(coeff_bit_count); multiply_truncate_uint_uint(plain_modulus_.pointer(), coeff_div_plain_modulus_.pointer(), coeff_uint64_count, upper_half_increment_.pointer()); sub_uint_uint(coeff_modulus_.pointer(), upper_half_increment_.pointer(), coeff_uint64_count, upper_half_increment_.pointer()); // Widen coeff modulus. int product_coeff_bit_count = coeff_bit_count + coeff_bit_count + get_significant_bit_count(static_cast<uint64_t>(coeff_count)); int plain_modulus_bit_count = plain_modulus_.significant_bit_count(); int wide_bit_count = product_coeff_bit_count + plain_modulus_bit_count; int wide_uint64_count = divide_round_up(wide_bit_count, bits_per_uint64); wide_coeff_modulus_.resize(wide_bit_count); wide_coeff_modulus_ = coeff_modulus_; // Calculate wide_coeff_modulus_ / 2. wide_coeff_modulus_div_two_.resize(wide_bit_count); right_shift_uint(wide_coeff_modulus_.pointer(), 1, wide_uint64_count, wide_coeff_modulus_div_two_.pointer()); // Initialize moduli. polymod_ = PolyModulus(poly_modulus_.pointer(), coeff_count, coeff_uint64_count); if (mode_ == TEST_MODE) { mod_ = Modulus(plain_modulus_.pointer(), coeff_uint64_count, pool_); } else { mod_ = Modulus(coeff_modulus_.pointer(), coeff_uint64_count, pool_); } }