//-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ for ( int i = 0; i < 4; i++ ) { if ( select_point(ofVec2f(x, y), quadmesh.getPos(i), 10) ){ id = i; return; } } }
void mouse(int button, int state, int x, int y) { frame_x = (float) x / (VPw/2) - 1.0; //formula derived from example on pg. 100 of frame_y = (float) (VPh - y) / (VPh/2) - 1.0; // Interactive Computer Graphics textbook //---------------------------------------------------------------------------------------------- //control point selection if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { move_index = select_point(frame_x, frame_y); //Returns index number of a control point. //Returns -1 if no point is present at cursor's coordinates if (move_index > -1) { if (grab > -1) { colors[grab] = color4(1.0, 0.0, 0.0, 1.0); // make previously selected control point red (deselected) } grab = move_index; colors[grab] = color4(0.0, 1.0, 0.0, 1.0); // make selected control point green } if (grab > -1) { control_points[grab] = point4(frame_x, frame_y, 0.0, 1.0); colors[grab] = color4(0.0, 1.0, 0.0, 1.0); // make selected control point green } glutPostRedisplay(); } //---------------------------------------------------------------------------------------------- //deselect points (disable editing of point) if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { if (grab > -1) { colors[grab] = color4(1.0, 0.0, 0.0, 1.0); // make selected control point red glutPostRedisplay(); grab = -1; } } //---------------------------------------------------------------------------------------------- //Create new control points if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { control_points[control_index] = point4(frame_x, frame_y, 0.0, 1.0); colors[control_index] = color4(1.0, 0.0, 0.0, 1.0); // make new control point red ++control_index; ++num_controls; glutPostRedisplay(); } }
/* Once we have found a D and q, this will find a curve and point. * Returns: 0 (composite), 1 (didn't work), 2 (success) * It's debatable what to do with a 1 return. */ static int find_curve(mpz_t a, mpz_t b, mpz_t x, mpz_t y, long D, int poly_index, mpz_t m, mpz_t q, mpz_t N, int maxroots) { long nroots, npoints, i, rooti, unity, result; mpz_t g, t, t2; mpz_t* roots = 0; /* TODO: A better way to do this, I believe, would be to have the root * finder set up as an iterator. That way we'd get the first root, * try to find a curve, and probably we'd be done. Only if we tried * 10+ points on that root would we get another root. This would * probably be set up as a stack (array) of polynomials plus one * saved root (for when we solve a degree 2 poly). */ /* Step 1: Get the roots of the Hilbert class polynomial. */ nroots = find_roots(D, poly_index, N, &roots, maxroots); if (nroots == 0) return 1; /* Step 2: Loop selecting curves and trying points. * On average it takes about 3 points, but we'll try 100+. */ mpz_init(g); mpz_init(t); mpz_init(t2); npoints = 0; result = 1; for (rooti = 0; result == 1 && rooti < 50*nroots; rooti++) { /* Given this D and root, select curve a,b */ select_curve_params(a, b, g, D, roots, rooti % nroots, N, t); if (mpz_sgn(g) == 0) { result = 0; break; } /* See Cohen 5.3.1, page 231 */ unity = (D == -3) ? 6 : (D == -4) ? 4 : 2; for (i = 0; result == 1 && i < unity; i++) { if (i > 0) update_ab(a, b, D, g, N); npoints++; select_point(x, y, a, b, N, t, t2); result = ecpp_check_point(x, y, m, q, a, N, t, t2); } } if (npoints > 10 && get_verbose_level() > 0) printf(" # point finding took %ld points\n", npoints); if (roots != 0) { for (rooti = 0; rooti < nroots; rooti++) mpz_clear(roots[rooti]); Safefree(roots); } mpz_clear(g); mpz_clear(t); mpz_clear(t2); return result; }
/* Once we have found a D and q, this will find a curve and point. * Returns: 0 (composite), 1 (didn't work), 2 (success) * It's debatable what to do with a 1 return. */ static int find_curve(mpz_t a, mpz_t b, mpz_t x, mpz_t y, long D, mpz_t m, mpz_t q, mpz_t N) { long nroots, npoints, i, rooti, unity, result; mpz_t g, t, t2; mpz_t* roots = 0; int verbose = get_verbose_level(); /* Step 1: Get the roots of the Hilbert class polynomial. */ nroots = find_roots(D, N, &roots); if (nroots == 0) return 1; /* Step 2: Loop selecting curves and trying points. * On average it takes about 3 points, but we'll try 100+. */ mpz_init(g); mpz_init(t); mpz_init(t2); npoints = 0; result = 1; for (rooti = 0; result == 1 && rooti < 50*nroots; rooti++) { /* Given this D and root, select curve a,b */ select_curve_params(a, b, g, D, roots, rooti % nroots, N, t); if (mpz_sgn(g) == 0) { result = 0; break; } /* See Cohen 5.3.1, page 231 */ unity = (D == -3) ? 6 : (D == -4) ? 4 : 2; for (i = 0; result == 1 && i < unity; i++) { if (i > 0) update_ab(a, b, D, g, N); npoints++; select_point(x, y, a, b, N, t, t2); result = ecpp_check_point(x, y, m, q, a, N, t, t2); } } if (verbose && npoints > 10) printf(" # point finding took %ld points\n", npoints); if (roots != 0) { for (rooti = 0; rooti < nroots; rooti++) mpz_clear(roots[rooti]); Safefree(roots); } mpz_clear(g); mpz_clear(t); mpz_clear(t2); return result; }
// Interleaved point multiplication using precomputed point multiples: The // small point multiples 0*P, 1*P, ..., 17*P are in p_pre_comp, the scalar // in p_scalar, if non-NULL. If g_scalar is non-NULL, we also add this multiple // of the generator, using certain (large) precomputed multiples in g_pre_comp. // Output point (X, Y, Z) is stored in x_out, y_out, z_out. static void batch_mul(fe x_out, fe y_out, fe z_out, const uint8_t *p_scalar, const uint8_t *g_scalar, const fe p_pre_comp[17][3]) { // set nq to the point at infinity fe nq[3] = {{0},{0},{0}}, ftmp, tmp[3]; uint64_t bits; uint8_t sign, digit; // Loop over both scalars msb-to-lsb, interleaving additions of multiples // of the generator (two in each of the last 32 rounds) and additions of p // (every 5th round). int skip = 1; // save two point operations in the first round size_t i = p_scalar != NULL ? 255 : 31; for (;;) { // double if (!skip) { point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); } // add multiples of the generator if (g_scalar != NULL && i <= 31) { // first, look 32 bits upwards bits = get_bit(g_scalar, i + 224) << 3; bits |= get_bit(g_scalar, i + 160) << 2; bits |= get_bit(g_scalar, i + 96) << 1; bits |= get_bit(g_scalar, i + 32); // select the point to add, in constant time select_point(bits, 16, g_pre_comp[1], tmp); if (!skip) { point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0], tmp[1], tmp[2]); } else { fe_copy(nq[0], tmp[0]); fe_copy(nq[1], tmp[1]); fe_copy(nq[2], tmp[2]); skip = 0; } // second, look at the current position bits = get_bit(g_scalar, i + 192) << 3; bits |= get_bit(g_scalar, i + 128) << 2; bits |= get_bit(g_scalar, i + 64) << 1; bits |= get_bit(g_scalar, i); // select the point to add, in constant time select_point(bits, 16, g_pre_comp[0], tmp); point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0], tmp[1], tmp[2]); } // do other additions every 5 doublings if (p_scalar != NULL && i % 5 == 0) { bits = get_bit(p_scalar, i + 4) << 5; bits |= get_bit(p_scalar, i + 3) << 4; bits |= get_bit(p_scalar, i + 2) << 3; bits |= get_bit(p_scalar, i + 1) << 2; bits |= get_bit(p_scalar, i) << 1; bits |= get_bit(p_scalar, i - 1); ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); // select the point to add or subtract, in constant time. select_point(digit, 17, p_pre_comp, tmp); fe_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point. fe_cmovznz(tmp[1], sign, tmp[1], ftmp); if (!skip) { point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, tmp[0], tmp[1], tmp[2]); } else { fe_copy(nq[0], tmp[0]); fe_copy(nq[1], tmp[1]); fe_copy(nq[2], tmp[2]); skip = 0; } } if (i == 0) { break; } --i; } fe_copy(x_out, nq[0]); fe_copy(y_out, nq[1]); fe_copy(z_out, nq[2]); }