Current section

23 Versions

Jump to

Compare versions

3 files changed
+39 additions
-4 deletions
  @@ -11,4 +11,4 @@
11 11 {<<"Info">>,<<"http://ed25519.cr.yp.to">>}]}.
12 12 {<<"name">>,<<"ed25519">>}.
13 13 {<<"requirements">>,[]}.
14 - {<<"version">>,<<"1.3.3">>}.
14 + {<<"version">>,<<"1.4.0">>}.
  @@ -13,7 +13,7 @@ defmodule Ed25519 do
13 13
14 14 `config/config.exs`
15 15
16 - use Mix.Config
16 + import Config
17 17
18 18 # The hash function will be invoked as 'Blake2.hash2b(payload, 16)'
19 19 config :ed25519,
  @@ -113,9 +113,11 @@ defmodule Ed25519 do
113 113 _ -> {@p - x, y}
114 114 end
115 115
116 - if isoncurve(point), do: point, else: raise("Point off curve")
116 + if isoncurve(point), do: point, else: raise("Point off Edwards curve")
117 117 end
118 118
119 + defp decodepoint(_), do: raise("Provided value not a key")
120 +
119 121 defp isoncurve({x, y}), do: (-x * x + y * y - 1 - @d * x * x * y * y) |> mod(@p) == 0
120 122
121 123 @doc """
  @@ -168,6 +170,13 @@ defmodule Ed25519 do
168 170 end
169 171 end
170 172
173 + defp clamp(c) do
174 + c
175 + |> band(~~~7)
176 + |> band(~~~(128 <<< (8 * 31)))
177 + |> bor(64 <<< (8 * 31))
178 + end
179 +
171 180 @doc """
172 181 validate a signed message
173 182 """
  @@ -214,4 +223,30 @@ defmodule Ed25519 do
214 223 |> scalarmult(@base)
215 224 |> encodepoint
216 225 end
226 +
227 + @doc """
228 + Derive the x25519/curve25519 encryption key from the ed25519 signing key
229 +
230 +
231 + By converting an `EdwardsPoint` on the Edwards model to the corresponding `MontgomeryPoint` on the Montgomery model
232 +
233 + Handles either `:secret` or `:public` keys as indicated in the call
234 +
235 + May `raise` on an invalid input key or unknown atom
236 +
237 + See: https://blog.filippo.io/using-ed25519-keys-for-encryption
238 + """
239 + @spec to_curve25519(key, atom) :: key
240 + def to_curve25519(key, which)
241 +
242 + def to_curve25519(ed_public_key, :public) do
243 + {_, y} = decodepoint(ed_public_key)
244 + u = mod((1 + y) * inv(1 - y), @p)
245 + <<u::little-size(256)>>
246 + end
247 +
248 + def to_curve25519(ed_secret_key, :secret) do
249 + <<digest32::little-size(256), _::binary-size(32)>> = :crypto.hash(:sha512, ed_secret_key)
250 + <<clamp(digest32)::little-size(256)>>
251 + end
217 252 end
  @@ -4,7 +4,7 @@ defmodule Ed25519.Mixfile do
4 4 def project do
5 5 [
6 6 app: :ed25519,
7 - version: "1.3.3",
7 + version: "1.4.0",
8 8 elixir: "~> 1.7",
9 9 name: "Ed25519",
10 10 source_url: "https://github.com/mwmiller/ed25519_ex",