Crypt-Bear

 view release on metacpan or  search on metacpan

src/ec/ec_p256_m15.c  view on Meta::CPAN

}

/*
 * Double a point in P-256. This function works for all valid points,
 * including the point at infinity.
 */
static void
p256_double(p256_jacobian *Q)
{
	/*
	 * Doubling formulas are:
	 *
	 *   s = 4*x*y^2
	 *   m = 3*(x + z^2)*(x - z^2)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y^4
	 *   z' = 2*y*z
	 *
	 * These formulas work for all points, including points of order 2
	 * and points at infinity:
	 *   - If y = 0 then z' = 0. But there is no such point in P-256
	 *     anyway.
	 *   - If z = 0 then z' = 0.
	 */
	uint32_t t1[20], t2[20], t3[20], t4[20];
	int i;

	/*
	 * Compute z^2 in t1.

src/ec/ec_p256_m15.c  view on Meta::CPAN

 *   - If the result is not the point at infinity, then it is correct.
 *   - Otherwise, if the returned value is 1, then this is a case of
 *     P1+P2 == 0, so the result is indeed the point at infinity.
 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 */
static uint32_t
p256_add(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1 * z2^2
	 *   u2 = x2 * z1^2
	 *   s1 = y1 * z2^3
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1 * z2

src/ec/ec_p256_m15.c  view on Meta::CPAN

 *   - If the result is not the point at infinity, then it is correct.
 *   - Otherwise, if the returned value is 1, then this is a case of
 *     P1+P2 == 0, so the result is indeed the point at infinity.
 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 */
static uint32_t
p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1

src/ec/ec_p256_m31.c  view on Meta::CPAN

}

/*
 * Double a point in P-256. This function works for all valid points,
 * including the point at infinity.
 */
static void
p256_double(p256_jacobian *Q)
{
	/*
	 * Doubling formulas are:
	 *
	 *   s = 4*x*y^2
	 *   m = 3*(x + z^2)*(x - z^2)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y^4
	 *   z' = 2*y*z
	 *
	 * These formulas work for all points, including points of order 2
	 * and points at infinity:
	 *   - If y = 0 then z' = 0. But there is no such point in P-256
	 *     anyway.
	 *   - If z = 0 then z' = 0.
	 */
	uint32_t t1[9], t2[9], t3[9], t4[9];

	/*
	 * Compute z^2 in t1.
	 */

src/ec/ec_p256_m31.c  view on Meta::CPAN

 *   - If the result is not the point at infinity, then it is correct.
 *   - Otherwise, if the returned value is 1, then this is a case of
 *     P1+P2 == 0, so the result is indeed the point at infinity.
 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 */
static uint32_t
p256_add(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1 * z2^2
	 *   u2 = x2 * z1^2
	 *   s1 = y1 * z2^3
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1 * z2

src/ec/ec_p256_m31.c  view on Meta::CPAN

 *   - If the result is not the point at infinity, then it is correct.
 *   - Otherwise, if the returned value is 1, then this is a case of
 *     P1+P2 == 0, so the result is indeed the point at infinity.
 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 */
static uint32_t
p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1

src/ec/ec_p256_m62.c  view on Meta::CPAN

/*
 * Point doubling in Jacobian coordinates: point P is doubled.
 * Note: if the source point is the point-at-infinity, then the result is
 * still the point-at-infinity, which is correct. Moreover, if the three
 * coordinates were zero, then they still are zero in the returned value.
 */
static void
p256_double(p256_jacobian *P)
{
	/*
	 * Doubling formulas are:
	 *
	 *   s = 4*x*y^2
	 *   m = 3*(x + z^2)*(x - z^2)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y^4
	 *   z' = 2*y*z
	 *
	 * These formulas work for all points, including points of order 2
	 * and points at infinity:
	 *   - If y = 0 then z' = 0. But there is no such point in P-256
	 *     anyway.
	 *   - If z = 0 then z' = 0.
	 */
	uint64_t t1[5], t2[5], t3[5], t4[5];

	/*
	 * Compute z^2 in t1.
	 */

src/ec/ec_p256_m62.c  view on Meta::CPAN

 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 *
 * Note that you can get a returned value of 0 with a correct result,
 * e.g. if P1 and P2 have the same Y coordinate, but distinct X coordinates.
 */
static uint32_t
p256_add(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1 * z2^2
	 *   u2 = x2 * z1^2
	 *   s1 = y1 * z2^3
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1 * z2

src/ec/ec_p256_m62.c  view on Meta::CPAN

 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 *
 * Again, a value of 0 may be returned in some cases where the addition
 * result is correct.
 */
static uint32_t
p256_add_mixed(p256_jacobian *P1, const p256_affine *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1

src/ec/ec_p256_m62.c  view on Meta::CPAN

 * Point addition (mixed coordinates, complete): P1 is replaced with P1+P2.
 * This is a specialised function for the case when P2 is a non-zero point
 * in affine coordinates.
 *
 * This function returns the correct result in all cases.
 */
static uint32_t
p256_add_complete_mixed(p256_jacobian *P1, const p256_affine *P2)
{
	/*
	 * Addtions formulas, in the general case, are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1
	 *
	 * These formulas mishandle the two following cases:
	 *
	 *  - If P1 is the point-at-infinity (z1 = 0), then z3 is
	 *    incorrectly set to 0.
	 *
	 *  - If P1 = P2, then u1 = u2 and s1 = s2, and x3, y3 and z3
	 *    are all set to 0.
	 *
	 * However, if P1 + P2 = 0, then u1 = u2 but s1 != s2, and then
	 * we correctly get z3 = 0 (the point-at-infinity).
	 *
	 * To fix the case P1 = 0, we perform at the end a copy of P2
	 * over P1, conditional to z1 = 0.
	 *
	 * For P1 = P2: in that case, both h and r are set to 0, and
	 * we get x3, y3 and z3 equal to 0. We can test for that
	 * occurrence to make a mask which will be all-one if P1 = P2,
	 * or all-zero otherwise; then we can compute the double of P2
	 * and add it, combined with the mask, to (x3,y3,z3).
	 *
	 * Using the doubling formulas in p256_double() on (x2,y2),
	 * simplifying since P2 is affine (i.e. z2 = 1, implicitly),
	 * we get:
	 *   s = 4*x2*y2^2
	 *   m = 3*(x2 + 1)*(x2 - 1)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y2^4
	 *   z' = 2*y2
	 * which requires only 6 multiplications. Added to the 11
	 * multiplications of the normal mixed addition in Jacobian
	 * coordinates, we get a cost of 17 multiplications in total.

src/ec/ec_p256_m62.c  view on Meta::CPAN

	const unsigned char *x, size_t xlen,
	const unsigned char *y, size_t ylen, int curve)
{
	/*
	 * We might want to use Shamir's trick here: make a composite
	 * window of u*P+v*Q points, to merge the two doubling-ladders
	 * into one. This, however, has some complications:
	 *
	 *  - During the computation, we may hit the point-at-infinity.
	 *    Thus, we would need p256_add_complete_mixed() (complete
	 *    formulas for point addition), with a higher cost (17 muls
	 *    instead of 11).
	 *
	 *  - A 4-bit window would be too large, since it would involve
	 *    16*16-1 = 255 points. For the same window size as in the
	 *    p256_mul() case, we would need to reduce the window size
	 *    to 2 bits, and thus perform twice as many non-doubling
	 *    point additions.
	 *
	 *  - The window may itself contain the point-at-infinity, and
	 *    thus cannot be in all generality be made of affine points.

src/ec/ec_p256_m64.c  view on Meta::CPAN

 *
 * (Note: this is true even without the final reduction: if the three
 * coordinates are encoded as four words of value zero each, then the
 * result will also have all-zero coordinate encodings, not the alternate
 * encoding as the integer p.)
 */
static void
p256_double(p256_jacobian *P)
{
	/*
	 * Doubling formulas are:
	 *
	 *   s = 4*x*y^2
	 *   m = 3*(x + z^2)*(x - z^2)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y^4
	 *   z' = 2*y*z
	 *
	 * These formulas work for all points, including points of order 2
	 * and points at infinity:
	 *   - If y = 0 then z' = 0. But there is no such point in P-256
	 *     anyway.
	 *   - If z = 0 then z' = 0.
	 */
	uint64_t t1[4], t2[4], t3[4], t4[4];

	/*
	 * Compute z^2 in t1.
	 */

src/ec/ec_p256_m64.c  view on Meta::CPAN

 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 *
 * Note that you can get a returned value of 0 with a correct result,
 * e.g. if P1 and P2 have the same Y coordinate, but distinct X coordinates.
 */
static uint32_t
p256_add(p256_jacobian *P1, const p256_jacobian *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1 * z2^2
	 *   u2 = x2 * z1^2
	 *   s1 = y1 * z2^3
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1 * z2

src/ec/ec_p256_m64.c  view on Meta::CPAN

 *   - Otherwise, P1 == P2, so a "double" operation should have been
 *     performed.
 *
 * Again, a value of 0 may be returned in some cases where the addition
 * result is correct.
 */
static uint32_t
p256_add_mixed(p256_jacobian *P1, const p256_affine *P2)
{
	/*
	 * Addtions formulas are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1

src/ec/ec_p256_m64.c  view on Meta::CPAN

 * Point addition (mixed coordinates, complete): P1 is replaced with P1+P2.
 * This is a specialised function for the case when P2 is a non-zero point
 * in affine coordinates.
 *
 * This function returns the correct result in all cases.
 */
static uint32_t
p256_add_complete_mixed(p256_jacobian *P1, const p256_affine *P2)
{
	/*
	 * Addtions formulas, in the general case, are:
	 *
	 *   u1 = x1
	 *   u2 = x2 * z1^2
	 *   s1 = y1
	 *   s2 = y2 * z1^3
	 *   h = u2 - u1
	 *   r = s2 - s1
	 *   x3 = r^2 - h^3 - 2 * u1 * h^2
	 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
	 *   z3 = h * z1
	 *
	 * These formulas mishandle the two following cases:
	 *
	 *  - If P1 is the point-at-infinity (z1 = 0), then z3 is
	 *    incorrectly set to 0.
	 *
	 *  - If P1 = P2, then u1 = u2 and s1 = s2, and x3, y3 and z3
	 *    are all set to 0.
	 *
	 * However, if P1 + P2 = 0, then u1 = u2 but s1 != s2, and then
	 * we correctly get z3 = 0 (the point-at-infinity).
	 *
	 * To fix the case P1 = 0, we perform at the end a copy of P2
	 * over P1, conditional to z1 = 0.
	 *
	 * For P1 = P2: in that case, both h and r are set to 0, and
	 * we get x3, y3 and z3 equal to 0. We can test for that
	 * occurrence to make a mask which will be all-one if P1 = P2,
	 * or all-zero otherwise; then we can compute the double of P2
	 * and add it, combined with the mask, to (x3,y3,z3).
	 *
	 * Using the doubling formulas in p256_double() on (x2,y2),
	 * simplifying since P2 is affine (i.e. z2 = 1, implicitly),
	 * we get:
	 *   s = 4*x2*y2^2
	 *   m = 3*(x2 + 1)*(x2 - 1)
	 *   x' = m^2 - 2*s
	 *   y' = m*(s - x') - 8*y2^4
	 *   z' = 2*y2
	 * which requires only 6 multiplications. Added to the 11
	 * multiplications of the normal mixed addition in Jacobian
	 * coordinates, we get a cost of 17 multiplications in total.

src/ec/ec_p256_m64.c  view on Meta::CPAN

	const unsigned char *x, size_t xlen,
	const unsigned char *y, size_t ylen, int curve)
{
	/*
	 * We might want to use Shamir's trick here: make a composite
	 * window of u*P+v*Q points, to merge the two doubling-ladders
	 * into one. This, however, has some complications:
	 *
	 *  - During the computation, we may hit the point-at-infinity.
	 *    Thus, we would need p256_add_complete_mixed() (complete
	 *    formulas for point addition), with a higher cost (17 muls
	 *    instead of 11).
	 *
	 *  - A 4-bit window would be too large, since it would involve
	 *    16*16-1 = 255 points. For the same window size as in the
	 *    p256_mul() case, we would need to reduce the window size
	 *    to 2 bits, and thus perform twice as many non-doubling
	 *    point additions.
	 *
	 *  - The window may itself contain the point-at-infinity, and
	 *    thus cannot be in all generality be made of affine points.

src/ec/ec_prime_i15.c  view on Meta::CPAN


/*
 * Extra scratch registers available when there is no second operand (e.g.
 * for "double" and "affine").
 */
#define t8     3
#define t9     4
#define t10    5

/*
 * Doubling formulas are:
 *
 *   s = 4*x*y^2
 *   m = 3*(x + z^2)*(x - z^2)
 *   x' = m^2 - 2*s
 *   y' = m*(s - x') - 8*y^4
 *   z' = 2*y*z
 *
 * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it
 * should. This case should not happen anyway, because our curves have
 * prime order, and thus do not contain any point of order 2.
 *
 * If P is infinity (z = 0), then again the formulas yield infinity,
 * which is correct. Thus, this code works for all points.
 *
 * Cost: 8 multiplications
 */
static const uint16_t code_double[] = {
	/*
	 * Compute z^2 (in t1).
	 */
	MMUL(t1, Pz, Pz),

src/ec/ec_prime_i15.c  view on Meta::CPAN

	MSUB(t2, Px),
	MMUL(Py, t1, t2),
	MMUL(t4, t3, t3),
	MSUB(Py, t4),
	MSUB(Py, t4),

	ENDCODE
};

/*
 * Addtions formulas are:
 *
 *   u1 = x1 * z2^2
 *   u2 = x2 * z1^2
 *   s1 = y1 * z2^3
 *   s2 = y2 * z1^3
 *   h = u2 - u1
 *   r = s2 - s1
 *   x3 = r^2 - h^3 - 2 * u1 * h^2
 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
 *   z3 = h * z1 * z2

src/ec/ec_prime_i15.c  view on Meta::CPAN


	r = 1;

	/*
	 * Copy the two operands in the dedicated registers.
	 */
	memcpy(t[P1x], P1->c, 3 * I15_LEN * sizeof(uint16_t));
	memcpy(t[P2x], P2->c, 3 * I15_LEN * sizeof(uint16_t));

	/*
	 * Run formulas.
	 */
	for (u = 0;; u ++) {
		unsigned op, d, a, b;

		op = code[u];
		if (op == 0) {
			break;
		}
		d = (op >> 8) & 0x0F;
		a = (op >> 4) & 0x0F;

src/ec/ec_prime_i31.c  view on Meta::CPAN


/*
 * Extra scratch registers available when there is no second operand (e.g.
 * for "double" and "affine").
 */
#define t8     3
#define t9     4
#define t10    5

/*
 * Doubling formulas are:
 *
 *   s = 4*x*y^2
 *   m = 3*(x + z^2)*(x - z^2)
 *   x' = m^2 - 2*s
 *   y' = m*(s - x') - 8*y^4
 *   z' = 2*y*z
 *
 * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it
 * should. This case should not happen anyway, because our curves have
 * prime order, and thus do not contain any point of order 2.
 *
 * If P is infinity (z = 0), then again the formulas yield infinity,
 * which is correct. Thus, this code works for all points.
 *
 * Cost: 8 multiplications
 */
static const uint16_t code_double[] = {
	/*
	 * Compute z^2 (in t1).
	 */
	MMUL(t1, Pz, Pz),

src/ec/ec_prime_i31.c  view on Meta::CPAN

	MSUB(t2, Px),
	MMUL(Py, t1, t2),
	MMUL(t4, t3, t3),
	MSUB(Py, t4),
	MSUB(Py, t4),

	ENDCODE
};

/*
 * Addtions formulas are:
 *
 *   u1 = x1 * z2^2
 *   u2 = x2 * z1^2
 *   s1 = y1 * z2^3
 *   s2 = y2 * z1^3
 *   h = u2 - u1
 *   r = s2 - s1
 *   x3 = r^2 - h^3 - 2 * u1 * h^2
 *   y3 = r * (u1 * h^2 - x3) - s1 * h^3
 *   z3 = h * z1 * z2

src/ec/ec_prime_i31.c  view on Meta::CPAN


	r = 1;

	/*
	 * Copy the two operands in the dedicated registers.
	 */
	memcpy(t[P1x], P1->c, 3 * I31_LEN * sizeof(uint32_t));
	memcpy(t[P2x], P2->c, 3 * I31_LEN * sizeof(uint32_t));

	/*
	 * Run formulas.
	 */
	for (u = 0;; u ++) {
		unsigned op, d, a, b;

		op = code[u];
		if (op == 0) {
			break;
		}
		d = (op >> 8) & 0x0F;
		a = (op >> 4) & 0x0F;



( run in 0.305 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )