Current section

23 Versions

Jump to

Compare versions

4 files changed
+49 additions
-50 deletions
  @@ -1,6 +1,6 @@
1 1 The MIT License (MIT)
2 2
3 - Copyright (c) 2016-2017 Matt Miller, Bram Verburg
3 + Copyright (c) 2016 Matt Miller
4 4
5 5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 6 of this software and associated documentation files (the "Software"), to deal
  @@ -11,4 +11,4 @@
11 11 {<<"maintainers">>,[<<"Matt Miller">>]}.
12 12 {<<"name">>,<<"ed25519">>}.
13 13 {<<"requirements">>,[]}.
14 - {<<"version">>,<<"1.0.1">>}.
14 + {<<"version">>,<<"1.0.2">>}.
  @@ -15,19 +15,20 @@ defmodule Ed25519 do
15 15 """
16 16 @type signature :: binary
17 17
18 - @p 57896044618658097711785492504343953926634992332820282019728792003956564819949
19 - @l 7237005577332262213973186563042994240857116359379907606001950938285454250989
20 - @d -4513249062541557337682894930092624173785641285191125241628941591882900924598840740
21 - @i 19681161376707505956807079304988542015446066515923890162744021073123829784752
22 - @t254 28948022309329048855892746252171976963317496166410141009864396001978282409984
23 - @base {15112221349535400772501151409588531511454012693041857206046113283949847762202, 46316835694926478169428394003475163141307993866256225615783033603165251855960 }
18 + @p 57_896_044_618_658_097_711_785_492_504_343_953_926_634_992_332_820_282_019_728_792_003_956_564_819_949
19 + @l 7_237_005_577_332_262_213_973_186_563_042_994_240_857_116_359_379_907_606_001_950_938_285_454_250_989
20 + @d -4_513_249_062_541_557_337_682_894_930_092_624_173_785_641_285_191_125_241_628_941_591_882_900_924_598_840_740
21 + @i 19_681_161_376_707_505_956_807_079_304_988_542_015_446_066_515_923_890_162_744_021_073_123_829_784_752
22 + @t254 28_948_022_309_329_048_855_892_746_252_171_976_963_317_496_166_410_141_009_864_396_001_978_282_409_984
23 + @base {15_112_221_349_535_400_772_501_151_409_588_531_511_454_012_693_041_857_206_046_113_283_949_847_762_202,
24 + 46_316_835_694_926_478_169_428_394_003_475_163_141_307_993_866_256_225_615_783_033_603_165_251_855_960}
24 25
25 26 defp xrecover(y) do
26 - xx = (y*y-1) * inv(@d*y*y+1)
27 - x = expmod(xx,div(@p+3,8),@p)
28 - x = case (x*x - xx) |> mod(@p) do
27 + xx = (y * y - 1) * inv(@d * y * y + 1)
28 + x = expmod(xx, div(@p + 3, 8), @p)
29 + x = case (x * x - xx) |> mod(@p) do
29 30 0 -> x
30 - _ -> (x*@i) |> mod(@p)
31 + _ -> mod(x * @i, @p)
31 32 end
32 33 case x |> mod(2) do
33 34 0 -> @p - x
  @@ -35,21 +36,21 @@ defmodule Ed25519 do
35 36 end
36 37 end
37 38
38 - defp mod(x,_y) when x == 0, do: 0
39 - defp mod(x,y) when x > 0, do: rem(x,y)
40 - defp mod(x,y) when x < 0, do: (y + rem(x,y)) |> rem(y)
39 + defp mod(x, _y) when x == 0, do: 0
40 + defp mod(x, y) when x > 0, do: rem(x, y)
41 + defp mod(x, y) when x < 0, do: rem(y + rem(x, y), y)
41 42
42 - defp hash(m), do: :crypto.hash(:sha512,m)
43 + defp hash(m), do: :crypto.hash(:sha512, m)
43 44 defp hashint(m), do: m |> hash |> decodeint
44 45
45 46 # :crypto.mod_pow chokes on negative inputs, so we feed it positive values
46 47 # only and patch up the result if necessary
47 - defp expmod(_b,0,_m), do: 1
48 - defp expmod(b,e,m) when b > 0 do
49 - b |> :crypto.mod_pow(e,m) |> :binary.decode_unsigned
48 + defp expmod(_b, 0, _m), do: 1
49 + defp expmod(b, e, m) when b > 0 do
50 + b |> :crypto.mod_pow(e, m) |> :binary.decode_unsigned
50 51 end
51 - defp expmod(b,e,m) do
52 - i = b |> abs() |> :crypto.mod_pow(e,m) |> :binary.decode_unsigned
52 + defp expmod(b, e, m) do
53 + i = b |> abs() |> :crypto.mod_pow(e, m) |> :binary.decode_unsigned
53 54 cond do
54 55 mod(e, 2) == 0 -> i
55 56 i == 0 -> i
  @@ -59,14 +60,14 @@ defmodule Ed25519 do
59 60
60 61 defp inv(x), do: x |> expmod(@p - 2, @p)
61 62
62 - defp edwards({x1,y1}, {x2,y2}) do
63 - x = (x1*y2+x2*y1) * inv(1+@d*x1*x2*y1*y2)
64 - y = (y1*y2+x1*x2) * inv(1-@d*x1*x2*y1*y2)
65 - {mod(x,@p), mod(y,@p)}
63 + defp edwards({x1, y1}, {x2, y2}) do
64 + x = (x1 * y2 + x2 * y1) * inv(1 + @d * x1 * x2 * y1 * y2)
65 + y = (y1 * y2 + x1 * x2) * inv(1 - @d * x1 * x2 * y1 * y2)
66 + {mod(x, @p), mod(y, @p)}
66 67 end
67 68
68 69 defp encodeint(x), do: x |> :binary.encode_unsigned(:little)
69 - defp encodepoint({x,y}) do
70 + defp encodepoint({x, y}) do
70 71 y |> band(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
71 72 |> bor((x &&& 1) <<< 255)
72 73 |> encodeint
  @@ -79,19 +80,16 @@ defmodule Ed25519 do
79 80 y = decoded |> band(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
80 81 x = xrecover(y)
81 82 point = case (x &&& 1) do
82 - ^xc -> {x,y}
83 + ^xc -> {x, y}
83 84 _ -> {@p - x, y}
84 85 end
85 - cond do
86 - isoncurve(point) -> point
87 - true -> raise("Point off curve")
88 - end
86 + if isoncurve(point), do: point, else: raise("Point off curve")
89 87 end
90 88
91 - defp isoncurve({x,y}), do: (-x*x + y*y - 1 - @d*x*x*y*y) |> mod(@p) == 0
89 + defp isoncurve({x, y}), do: (-x * x + y * y - 1 - @d * x * x * y * y) |> mod(@p) == 0
92 90
93 - defp rightsize(n,s) when byte_size(n) == s, do: n
94 - defp rightsize(n,s) when byte_size(n) < s, do: rightsize(n<><<0>>, s)
91 + defp rightsize(n, s) when byte_size(n) == s, do: n
92 + defp rightsize(n, s) when byte_size(n) < s, do: rightsize(n <> <<0>>, s)
95 93
96 94 @doc """
97 95 Sign a message
  @@ -100,27 +98,27 @@ defmodule Ed25519 do
100 98 This adds significant overhead.
101 99 """
102 100 @spec signature(binary, key, key) :: signature
103 - def signature(m,sk,pk \\ nil)
104 - def signature(m,sk,nil), do: signature(m,sk,derive_public_key(sk))
105 - def signature(m,sk,pk) do
101 + def signature(m, sk, pk \\ nil)
102 + def signature(m, sk, nil), do: signature(m, sk, derive_public_key(sk))
103 + def signature(m, sk, pk) do
106 104 h = hash(sk)
107 105 a = a_from_hash(h)
108 - r = hashint(:binary.part(h,32,32)<>m)
106 + r = hashint(:binary.part(h, 32, 32) <> m)
109 107 bigr = r |> scalarmult(@base) |> encodepoint
110 - s = (r+ hashint(bigr<>pk<>m) * a) |> mod(@l)
111 - bigr<>encodeint(s) |> rightsize(64)
108 + s = mod(r + hashint(bigr <> pk <> m) * a, @l)
109 + bigr <> encodeint(s) |> rightsize(64)
112 110 end
113 111
114 112 defp a_from_hash(h) do
115 - @t254 + (h |> :binary.part(0,32) |> :binary.decode_unsigned(:little) |> band(0xf3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8))
113 + @t254 + (h |> :binary.part(0, 32) |> :binary.decode_unsigned(:little) |> band(0xf3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8))
116 114 end
117 115
118 - defp scalarmult(0, _pair), do: {0,1}
116 + defp scalarmult(0, _pair), do: {0, 1}
119 117 defp scalarmult(e, p) do
120 118 q = e |> div(2) |> scalarmult(p)
121 - q = edwards(q,q)
119 + q = edwards(q, q)
122 120 case (e &&& 1) do
123 - 1 -> edwards(q,p)
121 + 1 -> edwards(q, p)
124 122 _ -> q
125 123 end
126 124 end
  @@ -129,22 +127,22 @@ defmodule Ed25519 do
129 127 validate a signed message
130 128 """
131 129 @spec valid_signature?(signature, binary, key) :: boolean
132 - def valid_signature?(s,m,pk) when byte_size(s) == 64 and byte_size(pk) == 32 do
130 + def valid_signature?(s, m, pk) when byte_size(s) == 64 and byte_size(pk) == 32 do
133 131 <<for_r::binary-size(32), for_s::binary-size(32)>> = s
134 132 r = decodepoint(for_r)
135 133 a = decodepoint(pk)
136 134 s = decodeint(for_s)
137 - h = hashint(encodepoint(r)<>pk<>m)
138 - scalarmult(s,@base) == edwards(r,scalarmult(h,a))
135 + h = hashint(encodepoint(r) <> pk <> m)
136 + scalarmult(s, @base) == edwards(r, scalarmult(h, a))
139 137 end
140 - def valid_signature?(_s,_m_,_pk), do: false
138 + def valid_signature?(_s, _m_, _pk), do: false
141 139
142 140 @doc """
143 141 Generate a secret/public key pair
144 142
145 143 Returned tuple contains `{random_secret_key, derived_public_key}`
146 144 """
147 - @spec generate_key_pair :: {key,key}
145 + @spec generate_key_pair :: {key, key}
148 146 def generate_key_pair do
149 147 secret = :crypto.strong_rand_bytes(32)
150 148 {secret, derive_public_key(secret)}
  @@ -3,7 +3,7 @@ defmodule Ed25519.Mixfile do
3 3
4 4 def project do
5 5 [app: :ed25519,
6 - version: "1.0.1",
6 + version: "1.0.2",
7 7 elixir: "~> 1.4",
8 8 name: "Ed25519",
9 9 source_url: "https://github.com/mwmiller/ed25519_ex",
  @@ -22,6 +22,7 @@ defmodule Ed25519.Mixfile do
22 22 [
23 23 {:earmark, "~> 1.0", only: :dev},
24 24 {:ex_doc, "~> 0.14", only: :dev},
25 + {:credo, "~> 0.8", only: [:dev, :test]},
25 26 ]
26 27 end