Current section

23 Versions

Jump to

Compare versions

3 files changed
+40 additions
-9 deletions
  @@ -2,13 +2,13 @@
2 2 [{<<"GitHub">>,<<"https://github.com/mwmiller/ed25519_ex">>},
3 3 {<<"Info">>,<<"http://ed25519.cr.yp.to">>}]}.
4 4 {<<"name">>,<<"ed25519">>}.
5 - {<<"version">>,<<"1.5.0">>}.
5 + {<<"version">>,<<"1.5.1">>}.
6 6 {<<"description">>,<<"Ed25519 signature functions">>}.
7 7 {<<"elixir">>,<<"~> 1.7">>}.
8 - {<<"app">>,<<"ed25519">>}.
9 8 {<<"files">>,
10 9 [<<"lib">>,<<"lib/hash.ex">>,<<"lib/ed25519.ex">>,<<"mix.exs">>,
11 10 <<"README.md">>,<<"LICENSE">>]}.
11 + {<<"app">>,<<"ed25519">>}.
12 12 {<<"licenses">>,[<<"MIT">>]}.
13 13 {<<"requirements">>,[]}.
14 14 {<<"build_tools">>,[<<"mix">>]}.
  @@ -62,6 +62,28 @@ defmodule Ed25519 do
62 62 defp mod(x, y) when x > 0, do: rem(x, y)
63 63 defp mod(x, y) when x < 0, do: rem(y + rem(x, y), y)
64 64
65 + # Extended projective coordinates (X:Y:Z:T) where x=X/Z, y=Y/Z, xy=T/Z
66 + # Unified addition formula eliminates expensive inversions during scalarmult
67 +
68 + defp point_add({x1, y1, z1, t1}, {x2, y2, z2, t2}) do
69 + a = mod((y1 - x1) * (y2 - x2), @p)
70 + b = mod((y1 + x1) * (y2 + x2), @p)
71 + c = mod(2 * t1 * t2 * @d, @p)
72 + d = mod(2 * z1 * z2, @p)
73 + e = mod(b - a, @p)
74 + f = mod(d - c, @p)
75 + g = mod(d + c, @p)
76 + h = mod(b + a, @p)
77 + {mod(e * f, @p), mod(g * h, @p), mod(f * g, @p), mod(e * h, @p)}
78 + end
79 +
80 + defp to_projective({x, y}), do: {x, y, 1, mod(x * y, @p)}
81 +
82 + defp from_projective({x, y, z, _t}) do
83 + inv_z = inv(z)
84 + {mod(x * inv_z, @p), mod(y * inv_z, @p)}
85 + end
86 +
65 87 # __using__ Macro generates the hash function at compile time, which allows the
66 88 # hashing function to be configurable without runtime overhead
67 89 use Ed25519.Hash
  @@ -169,13 +191,21 @@ defmodule Ed25519 do
169 191
170 192 defp scalarmult(0, _pair), do: {0, 1}
171 193
172 - defp scalarmult(e, p) do
173 - q = e |> div(2) |> scalarmult(p)
174 - q = edwards(q, q)
194 + defp scalarmult(e, {_px, _py} = point) do
195 + point_proj = to_projective(point)
196 + scalarmult_proj(e, point_proj)
197 + |> from_projective()
198 + end
175 199
176 - case e &&& 1 do
177 - 1 -> edwards(q, p)
178 - _ -> q
200 + defp scalarmult_proj(0, _point_proj), do: {0, 1, 1, 0}
201 +
202 + defp scalarmult_proj(e, point_proj) do
203 + half = scalarmult_proj(div(e, 2), point_proj)
204 + doubled = point_add(half, half)
205 +
206 + case rem(e, 2) do
207 + 1 -> point_add(doubled, point_proj)
208 + _ -> doubled
179 209 end
180 210 end
  @@ -4,7 +4,7 @@ defmodule Ed25519.Mixfile do
4 4 def project do
5 5 [
6 6 app: :ed25519,
7 - version: "1.5.0",
7 + version: "1.5.1",
8 8 elixir: "~> 1.7",
9 9 name: "Ed25519",
10 10 source_url: "https://github.com/mwmiller/ed25519_ex",
  @@ -22,6 +22,7 @@ defmodule Ed25519.Mixfile do
22 22
23 23 defp deps do
24 24 [
25 + {:benchee, "~> 1.3", only: :dev},
25 26 {:ex_doc, "~> 0.23", only: :dev},
26 27 {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
27 28 {:dialyxir, "~> 1.4", only: [:dev], runtime: false}