Current section
23 Versions
Jump to
Current section
23 Versions
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", |