Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Nettle
nettle
Commits
889a582f
Commit
889a582f
authored
Nov 21, 2019
by
Niels Möller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'curve448' into master
parents
85fd4910
5fffda51
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
285 additions
and
234 deletions
+285
-234
ChangeLog
ChangeLog
+38
-0
ecc-192.c
ecc-192.c
+4
-1
ecc-224.c
ecc-224.c
+4
-1
ecc-25519.c
ecc-25519.c
+5
-2
ecc-256.c
ecc-256.c
+4
-1
ecc-384.c
ecc-384.c
+4
-1
ecc-521.c
ecc-521.c
+4
-1
ecc-eh-to-a.c
ecc-eh-to-a.c
+5
-4
ecc-internal.h
ecc-internal.h
+12
-9
ecc-mul-a-eh.c
ecc-mul-a-eh.c
+6
-6
ecc-mul-g-eh.c
ecc-mul-g-eh.c
+2
-2
eccdata.c
eccdata.c
+150
-151
eddsa-sign.c
eddsa-sign.c
+1
-1
testsuite/ecc-add-test.c
testsuite/ecc-add-test.c
+33
-38
testsuite/ecc-dup-test.c
testsuite/ecc-dup-test.c
+13
-16
No files found.
ChangeLog
View file @
889a582f
2019-11-21 Niels Möller <nisse@lysator.liu.se>
* Merge curve448 preparations, from September 2017.
2017-09-23 Niels Möller <nisse@lysator.liu.se>
* eccdata.c: Reorganize curve25519 precomputation to work directly
with the twisted Edwards curve, with new point addition based on a
patch from Daiki Ueno.
* ecc-25519.c (_nettle_curve25519): Update for removed Montgomery
curve constant.
* ecc-internal.h (struct ecc_curve): Delete unused pointer
edwards_root. Update all instances.
* eccdata.c (output_curve): Don't output it.
* testsuite/ecc-add-test.c (test_main): Reduce test duplication.
Use ecc->add_hhh_itch.
* testsuite/ecc-dup-test.c (test_main): Reduce test duplication.
Use ecc->dup_itch.
2017-09-23 Daiki Ueno <dueno@redhat.com>
* ecc-eh-to-a.c (ecc_eh_to_a): Use ecc->q.bit_size, instead of
hard-coded value for curve25519.
* eddsa-sign.c (_eddsa_sign): Likewise.
* ecc-internal.h (ecc_dup_func): New typedef.
(struct ecc_curve): New constants add_hh_itch and dup_itch, new
function pointers add_hh and dup.
* ecc-192.c, ecc-224.c, ecc-256.c, ecc-384.c, ecc-521.c,
ecc-25519.c: Update accordingly.
* ecc-mul-g-eh.c (ecc_mul_g_eh): Use new function pointers.
* ecc-mul-a-eh.c (ecc_mul_a_eh, table_init, ecc_mul_a_eh):
Likewise.
* testsuite/ecc-dup-test.c (test_main): Likewise.
* testsuite/ecc-add-test.c (test_main): Likewise.
2019-10-01 Niels Möller <nisse@lysator.liu.se>
* testsuite/testutils.c (test_cipher_cfb8): Reset destination area
...
...
ecc-192.c
View file @
889a582f
...
...
@@ -155,19 +155,22 @@ const struct ecc_curve _nettle_secp_192r1 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_JJA_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_JJJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_JJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_ITCH
(
ECC_LIMB_SIZE
),
ECC_J_TO_A_ITCH
(
ECC_LIMB_SIZE
),
ecc_add_jja
,
ecc_add_jjj
,
ecc_dup_jj
,
ecc_mul_a
,
ecc_mul_g
,
ecc_j_to_a
,
ecc_b
,
ecc_g
,
NULL
,
ecc_unit
,
ecc_table
};
...
...
ecc-224.c
View file @
889a582f
...
...
@@ -107,19 +107,22 @@ const struct ecc_curve _nettle_secp_224r1 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_JJA_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_JJJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_JJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_ITCH
(
ECC_LIMB_SIZE
),
ECC_J_TO_A_ITCH
(
ECC_LIMB_SIZE
),
ecc_add_jja
,
ecc_add_jjj
,
ecc_dup_jj
,
ecc_mul_a
,
ecc_mul_g
,
ecc_j_to_a
,
ecc_b
,
ecc_g
,
NULL
,
ecc_unit
,
ecc_table
};
...
...
ecc-25519.c
View file @
889a582f
...
...
@@ -335,19 +335,22 @@ const struct ecc_curve _nettle_curve25519 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_EH_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_EHH_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_EH_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_EH_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_EH_ITCH
(
ECC_LIMB_SIZE
),
ECC_EH_TO_A_ITCH
(
ECC_LIMB_SIZE
,
ECC_25519_INV_ITCH
),
ecc_add_eh
,
ecc_add_ehh
,
ecc_dup_eh
,
ecc_mul_a_eh
,
ecc_mul_g_eh
,
ecc_eh_to_a
,
ecc_
d
,
/*
Use the
Edwards curve constant. */
ecc_
b
,
/* Edwards curve constant. */
ecc_g
,
ecc_edwards
,
ecc_unit
,
ecc_table
};
ecc-256.c
View file @
889a582f
...
...
@@ -284,19 +284,22 @@ const struct ecc_curve _nettle_secp_256r1 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_JJA_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_JJJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_JJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_ITCH
(
ECC_LIMB_SIZE
),
ECC_J_TO_A_ITCH
(
ECC_LIMB_SIZE
),
ecc_add_jja
,
ecc_add_jjj
,
ecc_dup_jj
,
ecc_mul_a
,
ecc_mul_g
,
ecc_j_to_a
,
ecc_b
,
ecc_g
,
NULL
,
ecc_unit
,
ecc_table
};
...
...
ecc-384.c
View file @
889a582f
...
...
@@ -192,19 +192,22 @@ const struct ecc_curve _nettle_secp_384r1 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_JJA_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_JJJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_JJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_ITCH
(
ECC_LIMB_SIZE
),
ECC_J_TO_A_ITCH
(
ECC_LIMB_SIZE
),
ecc_add_jja
,
ecc_add_jjj
,
ecc_dup_jj
,
ecc_mul_a
,
ecc_mul_g
,
ecc_j_to_a
,
ecc_b
,
ecc_g
,
NULL
,
ecc_unit
,
ecc_table
};
...
...
ecc-521.c
View file @
889a582f
...
...
@@ -120,19 +120,22 @@ const struct ecc_curve _nettle_secp_521r1 =
ECC_PIPPENGER_K
,
ECC_PIPPENGER_C
,
ECC_ADD_JJA_ITCH
(
ECC_LIMB_SIZE
),
ECC_ADD_JJJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_DUP_JJ_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_A_ITCH
(
ECC_LIMB_SIZE
),
ECC_MUL_G_ITCH
(
ECC_LIMB_SIZE
),
ECC_J_TO_A_ITCH
(
ECC_LIMB_SIZE
),
ecc_add_jja
,
ecc_add_jjj
,
ecc_dup_jj
,
ecc_mul_a
,
ecc_mul_g
,
ecc_j_to_a
,
ecc_b
,
ecc_g
,
NULL
,
ecc_unit
,
ecc_table
};
...
...
ecc-eh-to-a.c
View file @
889a582f
...
...
@@ -68,12 +68,13 @@ ecc_eh_to_a (const struct ecc_curve *ecc,
/* Skip y coordinate */
if
(
op
>
1
)
{
/* Reduce modulo q. FIXME: Hardcoded for curve25519,
duplicates end of ecc_25519_modq. FIXME: Is this needed
at all? Full reduction mod p is maybe sufficient. */
/* Reduce modulo q. Hardcoded for curve25519, duplicates end
of ecc_25519_modq. FIXME: Is this needed at all? op > 0
is only used by ecdsa code, and ecdsa on Edwards curves
makes little sense and is is only used by tests. */
unsigned
shift
;
assert
(
ecc
->
p
.
bit_size
==
255
);
shift
=
252
-
GMP_NUMB_BITS
*
(
ecc
->
p
.
size
-
1
);
shift
=
ecc
->
q
.
bit_size
-
1
-
GMP_NUMB_BITS
*
(
ecc
->
p
.
size
-
1
);
cy
=
mpn_submul_1
(
r
,
ecc
->
q
.
m
,
ecc
->
p
.
size
,
r
[
ecc
->
p
.
size
-
1
]
>>
shift
);
assert
(
cy
<
2
);
...
...
ecc-internal.h
View file @
889a582f
...
...
@@ -118,6 +118,10 @@ typedef void ecc_add_func (const struct ecc_curve *ecc,
const
mp_limb_t
*
p
,
const
mp_limb_t
*
q
,
mp_limb_t
*
scratch
);
typedef
void
ecc_dup_func
(
const
struct
ecc_curve
*
ecc
,
mp_limb_t
*
r
,
const
mp_limb_t
*
p
,
mp_limb_t
*
scratch
);
typedef
void
ecc_mul_g_func
(
const
struct
ecc_curve
*
ecc
,
mp_limb_t
*
r
,
const
mp_limb_t
*
np
,
mp_limb_t
*
scratch
);
...
...
@@ -174,12 +178,16 @@ struct ecc_curve
unsigned
short
pippenger_k
;
unsigned
short
pippenger_c
;
unsigned
short
add_hh_itch
;
unsigned
short
add_hhh_itch
;
unsigned
short
dup_itch
;
unsigned
short
mul_itch
;
unsigned
short
mul_g_itch
;
unsigned
short
h_to_a_itch
;
ecc_add_func
*
add_hh
;
ecc_add_func
*
add_hhh
;
ecc_dup_func
*
dup
;
ecc_mul_func
*
mul
;
ecc_mul_g_func
*
mul_g
;
ecc_h_to_a_func
*
h_to_a
;
...
...
@@ -189,9 +197,6 @@ struct ecc_curve
/* Generator, x coordinate followed by y (affine coordinates).
Currently used only by the test suite. */
const
mp_limb_t
*
g
;
/* If non-NULL, the constant needed for transformation to the
equivalent Edwards curve. */
const
mp_limb_t
*
edwards_root
;
/* For redc, same as B mod p, otherwise 1. */
const
mp_limb_t
*
unit
;
...
...
@@ -281,18 +286,16 @@ ecc_a_to_j (const struct ecc_curve *ecc,
/* Converts a point P in jacobian coordinates into a point R in affine
coordinates. If op == 1, produce x coordinate only. If op == 2,
produce the x coordinate only, and also reduce it modulo q. FIXME:
For the public interface, have separate functions for the three
cases, and use this flag argument only for the internal ecc->h_to_a
function. */
produce the x coordinate only, and also reduce it modulo q. */
void
ecc_j_to_a
(
const
struct
ecc_curve
*
ecc
,
int
op
,
mp_limb_t
*
r
,
const
mp_limb_t
*
p
,
mp_limb_t
*
scratch
);
/* Converts a point P on an Edwards curve to affine coordinates on
the corresponding Montgomery curve. */
/* Converts a point P in homogeneous coordinates on an Edwards curve
to affine coordinates. Meaning of op is the same as for
ecc_j_to_a. */
void
ecc_eh_to_a
(
const
struct
ecc_curve
*
ecc
,
int
op
,
...
...
ecc-mul-a-eh.c
View file @
889a582f
...
...
@@ -75,8 +75,8 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
{
int
digit
;
ecc
_
dup
_eh
(
ecc
,
r
,
r
,
scratch_out
);
ecc
_
add_
e
hh
(
ecc
,
tp
,
r
,
pe
,
scratch_out
);
ecc
->
dup
(
ecc
,
r
,
r
,
scratch_out
);
ecc
->
add_
h
hh
(
ecc
,
tp
,
r
,
pe
,
scratch_out
);
digit
=
(
w
&
bit
)
>
0
;
/* If we had a one-bit, use the sum. */
...
...
@@ -107,8 +107,8 @@ table_init (const struct ecc_curve *ecc,
for
(
j
=
2
;
j
<
size
;
j
+=
2
)
{
ecc
_
dup
_eh
(
ecc
,
TABLE
(
j
),
TABLE
(
j
/
2
),
scratch
);
ecc
_
add_
e
hh
(
ecc
,
TABLE
(
j
+
1
),
TABLE
(
j
),
TABLE
(
1
),
scratch
);
ecc
->
dup
(
ecc
,
TABLE
(
j
),
TABLE
(
j
/
2
),
scratch
);
ecc
->
add_
h
hh
(
ecc
,
TABLE
(
j
+
1
),
TABLE
(
j
),
TABLE
(
1
),
scratch
);
}
}
...
...
@@ -163,11 +163,11 @@ ecc_mul_a_eh (const struct ecc_curve *ecc,
bits
|=
w
>>
shift
;
}
for
(
j
=
0
;
j
<
ECC_MUL_A_EH_WBITS
;
j
++
)
ecc
_
dup
_eh
(
ecc
,
r
,
r
,
scratch_out
);
ecc
->
dup
(
ecc
,
r
,
r
,
scratch_out
);
bits
&=
TABLE_MASK
;
sec_tabselect
(
tp
,
3
*
ecc
->
p
.
size
,
table
,
TABLE_SIZE
,
bits
);
ecc
_
add_
e
hh
(
ecc
,
r
,
tp
,
r
,
scratch_out
);
ecc
->
add_
h
hh
(
ecc
,
r
,
tp
,
r
,
scratch_out
);
}
#undef table
#undef tp
...
...
ecc-mul-g-eh.c
View file @
889a582f
...
...
@@ -64,7 +64,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
for
(
i
=
k
;
i
--
>
0
;
)
{
ecc
_
dup
_eh
(
ecc
,
r
,
r
,
scratch
);
ecc
->
dup
(
ecc
,
r
,
r
,
scratch
);
for
(
j
=
0
;
j
*
c
<
bit_rows
;
j
++
)
{
unsigned
bits
;
...
...
@@ -93,7 +93,7 @@ ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r,
+
(
2
*
ecc
->
p
.
size
*
(
mp_size_t
)
j
<<
c
)),
1
<<
c
,
bits
);
ecc
_
add_
e
h
(
ecc
,
r
,
r
,
tp
,
scratch_out
);
ecc
->
add_
h
h
(
ecc
,
r
,
r
,
tp
,
scratch_out
);
}
}
#undef tp
...
...
eccdata.c
View file @
889a582f
...
...
@@ -2,7 +2,9 @@
Generate compile time constant (but machine dependent) tables.
Copyright (C) 2013, 2014 Niels Möller
Copyright (C) 2013, 2014, 2017 Niels Möller
Copyright (C) 2017 Daiki Ueno
Copyright (C) 2017 Red Hat, Inc.
This file is part of GNU Nettle.
...
...
@@ -53,8 +55,12 @@ enum ecc_type
{
/* y^2 = x^3 - 3x + b (mod p) */
ECC_TYPE_WEIERSTRASS
,
/* y^2 = x^3 + b x^2 + x */
ECC_TYPE_MONTGOMERY
#if 0
/* x^2 + y^2 = 1 - d x^2 y^2 */
ECC_TYPE_EDWARDS,
#endif
/* -x^2 + y^2 = 1 - d x^2 y^2 */
ECC_TYPE_TWISTED_EDWARDS
,
};
struct
ecc_curve
...
...
@@ -73,16 +79,6 @@ struct ecc_curve
mpz_t
q
;
struct
ecc_point
g
;
/* Non-zero if we want elements represented as point s(u, v) on an
equivalent Edwards curve, using
u = t x / y
v = (x-1) / (x+1)
*/
int
use_edwards
;
mpz_t
d
;
mpz_t
t
;
/* Table for pippenger's algorithm.
Element
...
...
@@ -127,9 +123,11 @@ ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q)
}
static
void
ecc_set_zero
(
struct
ecc_point
*
r
)
ecc_set_zero
(
const
struct
ecc_curve
*
ecc
,
struct
ecc_point
*
r
)
{
r
->
is_zero
=
1
;
mpz_set_ui
(
r
->
x
,
0
);
mpz_set_ui
(
r
->
y
,
ecc
->
type
!=
ECC_TYPE_WEIERSTRASS
);
}
static
void
...
...
@@ -140,13 +138,22 @@ ecc_set (struct ecc_point *r, const struct ecc_point *p)
mpz_set
(
r
->
y
,
p
->
y
);
}
static
void
ecc_add
(
const
struct
ecc_curve
*
ecc
,
struct
ecc_point
*
r
,
const
struct
ecc_point
*
p
,
const
struct
ecc_point
*
q
);
/* Needs to support in-place operation. */
static
void
ecc_dup
(
const
struct
ecc_curve
*
ecc
,
struct
ecc_point
*
r
,
const
struct
ecc_point
*
p
)
{
if
(
ecc
->
type
!=
ECC_TYPE_WEIERSTRASS
)
{
ecc_add
(
ecc
,
r
,
p
,
p
);
return
;
}
if
(
ecc_zero_p
(
p
))
ecc_set_zero
(
r
);
ecc_set_zero
(
ecc
,
r
);
else
{
...
...
@@ -161,32 +168,18 @@ ecc_dup (const struct ecc_curve *ecc,
mpz_mul_ui
(
m
,
p
->
y
,
2
);
mpz_invert
(
m
,
m
,
ecc
->
p
);
switch
(
ecc
->
type
)
{
case
ECC_TYPE_WEIERSTRASS
:
/* t = 3 (x^2 - 1) * m */
mpz_mul
(
t
,
p
->
x
,
p
->
x
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_sub_ui
(
t
,
t
,
1
);
mpz_mul_ui
(
t
,
t
,
3
);
break
;
case
ECC_TYPE_MONTGOMERY
:
/* t = (3 x^2 + 2 b x + 1) m = [x(3x+2b)+1] m */
mpz_mul_ui
(
t
,
ecc
->
b
,
2
);
mpz_addmul_ui
(
t
,
p
->
x
,
3
);
mpz_mul
(
t
,
t
,
p
->
x
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_add_ui
(
t
,
t
,
1
);
break
;
}
/* t = 3 (x^2 - 1) * m */
mpz_mul
(
t
,
p
->
x
,
p
->
x
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_sub_ui
(
t
,
t
,
1
);
mpz_mul_ui
(
t
,
t
,
3
);
mpz_mul
(
t
,
t
,
m
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
/* x' = t^2 - 2 x */
mpz_mul
(
x
,
t
,
t
);
mpz_submul_ui
(
x
,
p
->
x
,
2
);
if
(
ecc
->
type
==
ECC_TYPE_MONTGOMERY
)
mpz_sub
(
x
,
x
,
ecc
->
b
);
mpz_mod
(
x
,
x
,
ecc
->
p
);
...
...
@@ -208,55 +201,114 @@ ecc_dup (const struct ecc_curve *ecc,
}
static
void
ecc_add
(
const
struct
ecc_curve
*
ecc
,
struct
ecc_point
*
r
,
const
struct
ecc_point
*
p
,
const
struct
ecc_point
*
q
)
ecc_add
(
const
struct
ecc_curve
*
ecc
,
struct
ecc_point
*
r
,
const
struct
ecc_point
*
p
,
const
struct
ecc_point
*
q
)
{
if
(
ecc_zero_p
(
p
))
ecc_set
(
r
,
q
);
if
(
ecc
->
type
==
ECC_TYPE_WEIERSTRASS
)
{
if
(
ecc_zero_p
(
p
))
ecc_set
(
r
,
q
);
else
if
(
ecc_zero_p
(
q
))
ecc_set
(
r
,
p
);
else
if
(
ecc_zero_p
(
q
))
ecc_set
(
r
,
p
);
else
if
(
mpz_cmp
(
p
->
x
,
q
->
x
)
==
0
)
{
if
(
mpz_cmp
(
p
->
y
,
q
->
y
)
==
0
)
ecc_dup
(
ecc
,
r
,
p
);
else
if
(
mpz_cmp
(
p
->
x
,
q
->
x
)
==
0
)
{
if
(
mpz_cmp
(
p
->
y
,
q
->
y
)
==
0
)
ecc_dup
(
ecc
,
r
,
p
);
else
ecc_set_zero
(
ecc
,
r
);
}
else
ecc_set_zero
(
r
);
{
mpz_t
s
,
t
,
x
,
y
;
mpz_init
(
s
);
mpz_init
(
t
);
mpz_init
(
x
);
mpz_init
(
y
);
/* t = (q_y - p_y) / (q_x - p_x) */
mpz_sub
(
t
,
q
->
x
,
p
->
x
);
mpz_invert
(
t
,
t
,
ecc
->
p
);
mpz_sub
(
s
,
q
->
y
,
p
->
y
);
mpz_mul
(
t
,
t
,
s
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
/* x' = t^2 - p_x - q_x */
mpz_mul
(
x
,
t
,
t
);
mpz_sub
(
x
,
x
,
p
->
x
);
mpz_sub
(
x
,
x
,
q
->
x
);
mpz_mod
(
x
,
x
,
ecc
->
p
);
/* y' = (x - x') * t - y */
mpz_sub
(
y
,
p
->
x
,
x
);
mpz_mul
(
y
,
y
,
t
);
mpz_sub
(
y
,
y
,
p
->
y
);
mpz_mod
(
y
,
y
,
ecc
->
p
);
r
->
is_zero
=
0
;
mpz_swap
(
x
,
r
->
x
);
mpz_swap
(
y
,
r
->
y
);
mpz_clear
(
s
);
mpz_clear
(
t
);
mpz_clear
(
x
);
mpz_clear
(
y
);
}
}
else
{
/* Untwisted:
x = (p_x q_y + p_y q_x) / (1 - d p_x p_y q_x q_y)
y = (p_y q_y - p_x q_x) / (1 + d p_x p_y q_x q_y)
Twisted:
x = (p_x q_y + p_y q_x) / (1 - d p_x p_y q_x q_y)
y = (p_y q_y + p_x q_x) / (1 + d p_x p_y q_x q_y)
So they differ only by a sign in the expression for the new y
coordinate.
*/
mpz_t
s
,
t
,
x
,
y
;
mpz_init
(
s
);
mpz_init
(
t
);
mpz_init
(
x
);
mpz_init
(
y
);
/* t = (q_y - p_y) / (q_x - p_x) */
mpz_sub
(
t
,
q
->
x
,
p
->
x
);
mpz_invert
(
t
,
t
,
ecc
->
p
);
mpz_sub
(
s
,
q
->
y
,
p
->
y
);
mpz_mul
(
t
,
t
,
s
);
/* t = d p_x p_y q_x q_y */
mpz_mul
(
t
,
ecc
->
b
,
p
->
x
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_mul
(
t
,
t
,
p
->
y
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_mul
(
t
,
t
,
q
->
x
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
mpz_mul
(
t
,
t
,
q
->
y
);
mpz_mod
(
t
,
t
,
ecc
->
p
);
/* x' = t^2 - p_x - q_x */
mpz_mul
(
x
,
t
,
t
);
mpz_sub
(
x
,
x
,
p
->
x
);
mpz_sub
(
x
,
x
,
q
->
x
);
/* This appears to be the only difference between formulas. */
if
(
ecc
->
type
==
ECC_TYPE_MONTGOMERY
)
mpz_sub
(
x
,
x
,
ecc
->
b
);
/* x' = (p_x q_y + q_x p_y) / (1 - t) */
mpz_mul
(
x
,
p
->
x
,
q
->
y
);
mpz_mod
(
x
,
x
,
ecc
->
p
);
mpz_addmul
(
x
,
q
->
x
,
p
->
y
);
mpz_mod
(
x
,
x
,
ecc
->
p
);
mpz_ui_sub
(
s
,
1
,
t
);
mpz_invert
(
s
,
s
,
ecc
->
p
);
mpz_mul
(
x
,
x
,
s
);
mpz_mod
(
x
,
x
,
ecc
->
p
);
/* y' = (x - x') * t - y */
mpz_sub
(
y
,
p
->
x
,
x
);
mpz_mul
(
y
,
y
,
t
);
mpz_sub
(
y
,
y
,
p
->
y
);
/* y' = (p_y q_y - p_x q_x) / (1 + t) */
mpz_mul
(
y
,
p
->
y
,
q
->
y
);
mpz_mod
(
y
,
y
,
ecc
->
p
);
mpz_addmul
(
y
,
p
->
x
,
q
->
x
);
mpz_mod
(
y
,
y
,
ecc
->
p
);
mpz_add_ui
(
s
,
t
,
1
);
mpz_invert
(
s
,
s
,
ecc
->
p
);
mpz_mul
(
y
,
y
,
s
);
mpz_mod
(
y
,
y
,
ecc
->
p
);
r
->
is_zero
=
0
;
mpz_swap
(
x
,
r
->
x
);
mpz_swap
(
y
,
r
->
y
);
r
->
is_zero
=
(
mpz_cmp_ui
(
r
->
x
,
0
)
==
0
&&
mpz_cmp_ui
(
r
->
y
,
1
)
==
0
);
mpz_clear
(
s
);
mpz_clear
(
t
);
...
...
@@ -332,16 +384,6 @@ ecc_curve_init_str (struct ecc_curve *ecc, enum ecc_type type,
ecc
->
table
=
NULL
;
ecc
->
ref
=
NULL
;
mpz_init
(
ecc
->
d
);
mpz_init
(
ecc
->
t
);
ecc
->
use_edwards
=
(
t
!=
NULL
);
if
(
ecc
->
use_edwards
)
{
mpz_set_str
(
ecc
->
t
,
t
,
16
);
mpz_set_str
(
ecc
->
d
,
d
,
16
);
}
}
static
void
...
...
@@ -533,43 +575,37 @@ ecc_curve_init (struct ecc_curve *ecc, unsigned bit_size)
break
;
case
255
:
/* curve25519, y^2 = x^3 + 486662 x^2 + x (mod p), with p = 2^{255} - 19.
According to http://cr.yp.to/papers.html#newelliptic, this
is birationally equivalent to the Edwards curve
x^2 + y^2 = 1 + (121665/121666) x^2 y^2 (mod p).
/* Edwards curve used for eddsa25519 and curve25519,
And since the constant is not a square, the Edwards formulas
should be "complete", with no special cases needed for
doubling, neutral element, negatives, etc.
-x^2 + y^2 = 1 - (121665/121666) x^2 y^2, with p = 2^{255} - 19.
G
enerator is
x = 9, with y coordinate
14781619447589544791020593568409986887264606134616475288964881837755586237401,
according to
The g
enerator is
x = 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a
y = 0x6666666666666666666666666666666666666666666666666666666666666658
x = Mod(9, 2^
255
-
19
); sqrt(x^3 + 486662*x^2 + x)
Also birationally equivalent to the curve
25519
Montgomery curve,
in PARI/GP. Also, in PARI notation,
curve25519 = Mod([0, 486662, 0, 1, 0], 2^255-19)
*/
ecc_curve_init_str
(
ecc
,
ECC_TYPE_MONTGOMERY
,
y^2 = x^3 + 486662 x^2 + x (mod p)
*/
ecc_curve_init_str
(
ecc
,
ECC_TYPE_TWISTED_EDWARDS
,
"7fffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffed"
,
"76d06"
,
/* (121665/121666) mod p, from PARI/GP
c = Mod(121665, p); c / (c+1)
*/