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;