ecdsa_ext 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ffeb5bdada0b817b13c781070e239322058aa645a85440a6ef77bf87e5dea2d2
4
- data.tar.gz: 277175edaac373991a84de08987c3ec5d426410664f5e5d57a56f409a39ea8f5
3
+ metadata.gz: f71a8a1ec3a2e0fef42f9820fd59ba1f7d440ec86e0c85922da554f4d1f9d8f2
4
+ data.tar.gz: 7c1db1f1c79d783f307f2fac3185ed837882bd68b516770da063a5d08dd04755
5
5
  SHA512:
6
- metadata.gz: 2b9944ff8eaa893aec952088eb9d5fad70d550f9396eec59c76a5e070aa3e0752bef098e5d13982a0963b0eab2641faa10de665feede18305ac32bdc1ff73c69
7
- data.tar.gz: bff44997fbd4154ad6099dadd15661927dba01bdf8fd53182b70c1eca8c77ca6f4d08883b413d014b06f1530b8e43e0fe0a433ac3e9751a4b6cb49efcc73c331
6
+ metadata.gz: f2472cd8dbf5f124619222e00b55c661dcd74962a92a4decb5a4acaa31d281ed052177949875ae68d9b0ec581df2c602c1bc8e9dd72fa2409efebbdc5f51ae17
7
+ data.tar.gz: 8c4678914dae19af4f13408547ef95ee86041131541b37b68275a13c3da6f8d02641c134d4984e649d665f7c7eeb8d317e1a06a6a950128661c306bb29f98bb7
@@ -46,6 +46,10 @@ module ECDSA
46
46
  new(group, :infinity)
47
47
  end
48
48
 
49
+ def infinity_point
50
+ self.class.infinity_point(group)
51
+ end
52
+
49
53
  # Check whether infinity point or not.
50
54
  # @return [Boolean]
51
55
  def infinity?
@@ -3,9 +3,8 @@
3
3
  module ECDSA
4
4
  module Ext
5
5
  # Point of Jacobian coordinates
6
+ # http://point-at-infinity.org/ecc/Prime_Curve_Jacobian_Coordinates.html
6
7
  class JacobianPoint < AbstractPoint
7
- include JacobianArithmetic
8
-
9
8
  # Add this point to another point on the same curve.
10
9
  # @param [ECDSA::Ext::JacobianPoint] other
11
10
  # @return [ECDSA::Ext::JacobianPoint]
@@ -20,37 +19,21 @@ module ECDSA
20
19
  return other if infinity?
21
20
  return self if other.infinity?
22
21
 
23
- if x == other.x && y == field.mod(-other.y) && z == other.z
24
- return JacobianPoint.infinity_point(group)
25
- end
26
-
27
- return other if y.zero? || z.zero?
28
- return self if other.y.zero? || other.z.zero?
22
+ u1 = field.mod(x * field.power(other.z, 2))
23
+ u2 = field.mod(other.x * field.power(z, 2))
24
+ s1 = field.mod(y * field.power(other.z, 3))
25
+ s2 = field.mod(other.y * field.power(z, 3))
29
26
 
30
- unless x == other.x
31
- new_point =
32
- if z == other.z
33
- z == 1 ? add_with_z_one(self, other) : add_with_z_eq(self, other)
34
- elsif z == 1
35
- add_with_z2_one(other, self)
36
- elsif other.z == 1
37
- add_with_z2_one(self, other)
38
- else
39
- add_with_z_ne(self, other)
40
- end
41
- return(
42
- (
43
- if new_point.y.zero? || new_point.z.zero?
44
- JacobianPoint.infinity_point(group)
45
- else
46
- new_point
47
- end
48
- )
49
- )
50
- end
27
+ return s1 == s2 ? double : infinity_point if u1 == u2
51
28
 
52
- return double if self == other
53
- raise "Failed to add #{inspect} to #{other.inspect}: No addition rules matched."
29
+ h = field.mod(u2 - u1)
30
+ h2 = field.power(h, 2)
31
+ h3 = field.power(h, 3)
32
+ r = field.mod(s2 - s1)
33
+ x3 = field.mod(field.power(r, 2) - h3 - 2 * u1 * h2)
34
+ y3 = field.mod(r * (u1 * h2 - x3) - s1 * h3)
35
+ z3 = field.mod(h * z * other.z)
36
+ JacobianPoint.new(group, x3, y3, z3)
54
37
  end
55
38
  alias + add_to_point
56
39
 
@@ -58,19 +41,14 @@ module ECDSA
58
41
  # @return [ECDSA::Ext::JacobianPoint]
59
42
  def double
60
43
  return self if infinity?
44
+ return infinity_point if y.zero?
61
45
 
62
- return double_with_z_one(self) if z == 1
63
-
64
- xx = field.square(x)
65
- yy = field.square(y)
66
- yyyy = field.square(yy)
67
- zz = field.square(z)
68
- s = field.mod(2 * (field.square(x + yy) - xx - yyyy))
69
- m = field.mod(3 * xx + group.param_a * zz * zz)
70
- t = field.mod(m * m - 2 * s)
71
- y3 = field.mod(m * (s - t) - 8 * yyyy)
72
- z3 = field.mod(field.square(y + z) - yy - zz)
73
- JacobianPoint.new(group, t, y3, z3)
46
+ s = field.mod(4 * x * field.power(y, 2))
47
+ m = field.mod(3 * field.power(x, 2) + group.param_a * field.power(z, 4))
48
+ x3 = field.mod(field.power(m, 2) - 2 * s)
49
+ y3 = field.mod(m * (s - x3) - 8 * field.power(y, 4))
50
+ z3 = field.mod(2 * y * z)
51
+ JacobianPoint.new(group, x3, y3, z3)
74
52
  end
75
53
 
76
54
  # Convert this coordinates to affine coordinates.
@@ -103,28 +81,6 @@ module ECDSA
103
81
 
104
82
  lhs_x == rhs_x && lhs_y == rhs_y
105
83
  end
106
-
107
- private
108
-
109
- def double_non_const
110
- return self if infinity?
111
- z == 1 ? double_z1 : double
112
- end
113
-
114
- def double_z1
115
- z3 = field.mod(2 * y)
116
- a = field.square(x)
117
- b = field.square(y)
118
- c = field.square(b)
119
- b = field.square(x + b)
120
- d = field.mod(2 * (b - (a + c)))
121
- e = field.mod(a * 3)
122
- f = field.square(e)
123
- x3 = field.mod(f - (2 * d))
124
- f = field.mod(d - x3)
125
- y3 = field.mod(e * f - 8 * c)
126
- JacobianPoint.new(group, x3, y3, z3)
127
- end
128
84
  end
129
85
  end
130
86
  end
@@ -3,9 +3,8 @@
3
3
  module ECDSA
4
4
  module Ext
5
5
  # Representing a point on elliptic curves using projective coordinates.
6
+ # http://point-at-infinity.org/ecc/Prime_Curve_Standard_Projective_Coordinates.html
6
7
  class ProjectivePoint < AbstractPoint
7
- include ProjectiveArithmetic
8
-
9
8
  # Add this point to another point on the same curve.
10
9
  # @param [ECDSA::Ext::ProjectivePoint] other
11
10
  # @return [ECDSA::Ext::ProjectivePoint]
@@ -20,30 +19,21 @@ module ECDSA
20
19
  return other if infinity?
21
20
  return self if other.infinity?
22
21
 
23
- if x == other.x && y == field.mod(-other.y) && z == other.z
24
- return ProjectivePoint.infinity_point(group)
25
- end
26
-
27
- unless x == other.x
28
- new_point =
29
- if group.param_a == field.mod(-3)
30
- addition_negative3(self, other)
31
- else
32
- addition_any(self, other)
33
- end
34
- return(
35
- (
36
- if new_point.y.zero? || new_point.z.zero?
37
- JacobianPoint.infinity_point(group)
38
- else
39
- new_point
40
- end
41
- )
42
- )
43
- end
44
-
45
- return double if self == other
46
- raise "Failed to add #{inspect} to #{other.inspect}: No addition rules matched."
22
+ u1 = field.mod(other.y * z)
23
+ u2 = field.mod(y * other.z)
24
+ v1 = field.mod(other.x * z)
25
+ v2 = field.mod(x * other.z)
26
+ return u1 == u2 ? double : infinity_point if v1 == v2
27
+ u = field.mod(u1 - u2)
28
+ v = field.mod(v1 - v2)
29
+ vv = field.power(v, 2)
30
+ vvv = field.power(v, 3)
31
+ w = field.mod(z * other.z)
32
+ a = field.mod(field.power(u, 2) * w - vvv - 2 * vv * v2)
33
+ x3 = field.mod(v * a)
34
+ y3 = field.mod(u * (vv * v2 - a) - vvv * u2)
35
+ z3 = field.mod(vvv * w)
36
+ ProjectivePoint.new(group, x3, y3, z3)
47
37
  end
48
38
  alias + add_to_point
49
39
 
@@ -51,12 +41,17 @@ module ECDSA
51
41
  # @return [ECDSA::Ext::ProjectivePoint]
52
42
  def double
53
43
  return self if infinity?
44
+ return infinity_point if y.zero?
54
45
 
55
- if group.param_a == field.mod(-3)
56
- double_negative3(self)
57
- else
58
- double_any(self)
59
- end
46
+ w = field.mod(group.param_a * field.power(z, 2) + 3 * field.power(x, 2))
47
+ s = field.mod(y * z)
48
+ b = field.mod(x * y * s)
49
+ h = field.mod(field.power(w, 2) - 8 * b)
50
+ x3 = field.mod(2 * h * s)
51
+ y3 =
52
+ field.mod(w * (4 * b - h) - 8 * field.power(y, 2) * field.power(s, 2))
53
+ z3 = field.mod(8 * field.power(s, 3))
54
+ ProjectivePoint.new(group, x3, y3, z3)
60
55
  end
61
56
 
62
57
  # Convert this coordinates to affine coordinates.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ECDSA
4
4
  module Ext
5
- VERSION = "0.4.2"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
data/lib/ecdsa/ext.rb CHANGED
@@ -5,9 +5,7 @@ module ECDSA
5
5
  # Extension for ecdsa gem.
6
6
  module Ext
7
7
  autoload :AbstractPoint, "ecdsa/ext/abstract_point"
8
- autoload :ProjectiveArithmetic, "ecdsa/ext/projective_arithmetic"
9
8
  autoload :ProjectivePoint, "ecdsa/ext/projective_point"
10
- autoload :JacobianArithmetic, "ecdsa/ext/jacobian_arithmetic"
11
9
  autoload :JacobianPoint, "ecdsa/ext/jacobian_point"
12
10
  end
13
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecdsa_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-28 00:00:00.000000000 Z
11
+ date: 2023-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ecdsa
@@ -47,10 +47,8 @@ files:
47
47
  - ecdsa_ext.gemspec
48
48
  - lib/ecdsa/ext.rb
49
49
  - lib/ecdsa/ext/abstract_point.rb
50
- - lib/ecdsa/ext/jacobian_arithmetic.rb
51
50
  - lib/ecdsa/ext/jacobian_point.rb
52
51
  - lib/ecdsa/ext/point.rb
53
- - lib/ecdsa/ext/projective_arithmetic.rb
54
52
  - lib/ecdsa/ext/projective_point.rb
55
53
  - lib/ecdsa/ext/sign_verify.rb
56
54
  - lib/ecdsa/ext/version.rb
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
- module ECDSA
3
- module Ext
4
- # Point arithmetic implementation
5
- module JacobianArithmetic
6
- def add_with_z_one(a, b)
7
- field = a.field
8
- h = field.mod(b.x - a.x)
9
- hh = field.square(h)
10
- i = field.mod(4 * hh)
11
- j = field.mod(h * i)
12
- r = field.mod(2 * (b.y - a.y))
13
- return double_with_z_one(a) if h.zero? && r.zero?
14
- v = field.mod(a.x * i)
15
- x3 = field.mod(field.square(r) - j - 2 * v)
16
- y3 = field.mod(r * (v - x3) - 2 * a.y * j)
17
- z3 = field.mod(2 * h)
18
- JacobianPoint.new(a.group, x3, y3, z3)
19
- end
20
-
21
- def add_with_z_eq(a, b)
22
- field = a.field
23
- a = field.square(field.mod(b.x - a.x))
24
- b = field.mod(a.x * a)
25
- c = field.mod(b.x * a)
26
- d = field.square(field.mod(b.y - a.y))
27
- return double(a) if a.zero? && d.zero?
28
- x3 = field.mod(d - b - c)
29
- y3 = field.mod((b.y - a.y) * (b - x3) - a.y * (c - b))
30
- z3 = field.mod(a.z * (b.x - a.x))
31
- JacobianPoint.new(a.group, x3, y3, z3)
32
- end
33
-
34
- def add_with_z2_one(a, b)
35
- field = a.field
36
- z1z1 = field.square(a.z)
37
- u2 = field.mod(b.x * z1z1)
38
- s2 = field.mod(b.y * a.z * z1z1)
39
- h = field.mod(u2 - a.x)
40
- hh = field.square(h)
41
- i = field.mod(4 * hh)
42
- j = field.mod(h * i)
43
- r = field.mod(2 * (s2 - a.y))
44
- return double_with_z_one(b) if r.zero? && h.zero?
45
- v = field.mod(a.x * i)
46
- x3 = field.mod(r * r - j - 2 * v)
47
- y3 = field.mod(r * (v - x3) - 2 * a.y * j)
48
- z3 = field.mod(field.square(a.z + h) - z1z1 - hh)
49
- JacobianPoint.new(a.group, x3, y3, z3)
50
- end
51
-
52
- def add_with_z_ne(a, b)
53
- field = a.field
54
- z1z1 = field.square(a.z)
55
- z2z2 = field.square(b.z)
56
- u1 = field.mod(a.x * z2z2)
57
- u2 = field.mod(b.x * z1z1)
58
- s1 = field.mod(a.y * b.z * z2z2)
59
- s2 = field.mod(b.y * a.z * z1z1)
60
- h = field.mod(u2 - u1)
61
- i = field.mod(4 * h * h)
62
- j = field.mod(h * i)
63
- r = field.mod(2 * (s2 - s1))
64
- return double(a) if h.zero? && r.zero?
65
- v = field.mod(u1 * i)
66
- x3 = field.mod(r * r - j - 2 * v)
67
- y3 = field.mod(r * (v - x3) - 2 * s1 * j)
68
- z3 = field.mod((field.square(a.z + b.z) - z1z1 - z2z2) * h)
69
- JacobianPoint.new(a.group, x3, y3, z3)
70
- end
71
-
72
- def double_with_z_one(point)
73
- field = point.field
74
- xx = field.square(point.x)
75
- yy = field.square(point.y)
76
- yyyy = field.square(yy)
77
- s = field.mod(2 * (field.square(point.x + yy) - xx - yyyy))
78
- m = field.mod(3 * xx + point.group.param_a)
79
- t = field.mod(m * m - 2 * s)
80
- y3 = field.mod(m * (s - t) - 8 * yyyy)
81
- z3 = field.mod(2 * point.y)
82
- JacobianPoint.new(point.group, t, y3, z3)
83
- end
84
- end
85
- end
86
- end
@@ -1,143 +0,0 @@
1
- # frozen_string_literal: true
2
- module ECDSA
3
- module Ext
4
- # Point arithmetic implementation
5
- module ProjectiveArithmetic
6
- def addition_negative3(a, b)
7
- field = a.field
8
- xx = field.mod(a.x * b.x)
9
- yy = field.mod(a.y * b.y)
10
- zz = field.mod(a.z * b.z)
11
- xy_pairs = field.mod((a.x + a.y) * (b.x + b.y) - (xx + yy))
12
- yz_pairs = field.mod((a.y + a.z) * (b.y + b.z) - (yy + zz))
13
- xz_pairs = field.mod((a.x + a.z) * (b.x + b.z) - (xx + zz))
14
-
15
- bzz_part = field.mod(xz_pairs - a.group.param_b * zz)
16
- bzz3_part = field.mod(bzz_part * 2 + bzz_part)
17
- yy_m_bzz3 = field.mod(yy - bzz3_part)
18
- yy_p_bzz3 = field.mod(yy + bzz3_part)
19
-
20
- zz3 = field.mod(zz * 3)
21
- bxz_part = field.mod(a.group.param_b * xz_pairs - (zz3 + xx))
22
- bxz3_part = field.mod(bxz_part * 3)
23
- xx3_m_zz3 = field.mod(xx * 3 - zz3)
24
-
25
- x = field.mod(yy_p_bzz3 * xy_pairs - yz_pairs * bxz3_part)
26
- y = field.mod(yy_p_bzz3 * yy_m_bzz3 + xx3_m_zz3 * bxz3_part)
27
- z = field.mod(yy_m_bzz3 * yz_pairs + xy_pairs * xx3_m_zz3)
28
- ProjectivePoint.new(a.group, x, y, z)
29
- end
30
-
31
- def addition_any(a, b)
32
- field = a.field
33
- b3 = field.mod(3 * group.param_b)
34
- t0 = field.mod(a.x * b.x)
35
- t1 = field.mod(a.y * b.y)
36
- t2 = field.mod(a.z * b.z)
37
- t3 = field.mod(a.x + a.y)
38
- t4 = field.mod(b.x + b.y)
39
- t3 = field.mod(t3 * t4)
40
- t4 = field.mod(t0 + t1)
41
- t3 = field.mod(t3 - t4)
42
- t4 = field.mod(a.x + a.z)
43
- t5 = field.mod(b.x + b.z)
44
- t4 = field.mod(t4 * t5)
45
- t5 = field.mod(t0 + t2)
46
- t4 = field.mod(t4 - t5)
47
- t5 = field.mod(a.y + a.z)
48
- x3 = field.mod(b.y + b.z)
49
- t5 = field.mod(t5 * x3)
50
- x3 = field.mod(t1 + t2)
51
- t5 = field.mod(t5 - x3)
52
- z3 = field.mod(a.group.param_a * t4)
53
- x3 = field.mod(b3 * t2)
54
- z3 = field.mod(x3 + z3)
55
- x3 = field.mod(t1 - z3)
56
- z3 = field.mod(t1 + z3)
57
- y3 = field.mod(x3 * z3)
58
- t1 = field.mod(t0 + t0)
59
- t1 = field.mod(t1 + t0)
60
- t2 = field.mod(a.group.param_a * t2)
61
- t4 = field.mod(b3 * t4)
62
- t1 = field.mod(t1 + t2)
63
- t2 = field.mod(t0 - t2)
64
- t2 = field.mod(a.group.param_a * t2)
65
- t4 = field.mod(t4 + t2)
66
- t0 = field.mod(t1 * t4)
67
- y3 = field.mod(y3 + t0)
68
- t0 = field.mod(t5 * t4)
69
- x3 = field.mod(t3 * x3)
70
- x3 = field.mod(x3 - t0)
71
- t0 = field.mod(t3 * t1)
72
- z3 = field.mod(t5 * z3)
73
- z3 = field.mod(z3 + t0)
74
- ProjectivePoint.new(a.group, x3, y3, z3)
75
- end
76
-
77
- def double_negative3(point)
78
- field = point.field
79
- xx = field.square(point.x)
80
- yy = field.square(point.y)
81
- zz = field.square(point.z)
82
- xy2 = field.mod(point.x * point.y * 2)
83
- xz2 = field.mod(point.x * point.z * 2)
84
-
85
- bzz_part = field.mod(point.group.param_b * zz - xz2)
86
- bzz3_part = field.mod(bzz_part + bzz_part + bzz_part)
87
- yy_m_bzz3 = field.mod(yy - bzz3_part)
88
- yy_p_bzz3 = field.mod(yy + bzz3_part)
89
- y_frag = field.mod(yy_p_bzz3 * yy_m_bzz3)
90
- x_frag = field.mod(yy_m_bzz3 * xy2)
91
-
92
- zz3 = field.mod(zz * 3)
93
- bxz2_part = field.mod(point.group.param_b * xz2 - (zz3 + xx))
94
- bxz6_part = field.mod(bxz2_part * 3)
95
- xx3_m_zz3 = field.mod(xx * 3 - zz3)
96
-
97
- y = field.mod(y_frag + xx3_m_zz3 * bxz6_part)
98
- yz2 = field.mod(point.y * point.z * 2)
99
- x = field.mod(x_frag - bxz6_part * yz2)
100
- z = field.mod(yz2 * yy * 4)
101
- ProjectivePoint.new(point.group, x, y, z)
102
- end
103
-
104
- def double_any(point)
105
- field = point.field
106
- b3 = field.mod(point.group.param_b * 3)
107
-
108
- t0 = field.mod(point.x * point.x)
109
- t1 = field.mod(point.y * point.y)
110
- t2 = field.mod(point.z * point.z)
111
- t3 = field.mod(point.x * point.y)
112
- t3 = field.mod(t3 + t3)
113
- z3 = field.mod(point.x * point.z)
114
- z3 = field.mod(z3 + z3)
115
- x3 = field.mod(point.group.param_a * z3)
116
- y3 = field.mod(b3 * t2)
117
- y3 = field.mod(x3 + y3)
118
- x3 = field.mod(t1 - y3)
119
- y3 = field.mod(t1 + y3)
120
- y3 = field.mod(x3 * y3)
121
- x3 = field.mod(t3 * x3)
122
- z3 = field.mod(b3 * z3)
123
- t2 = field.mod(point.group.param_a * t2)
124
- t3 = field.mod(t0 - t2)
125
- t3 = field.mod(point.group.param_a * t3)
126
- t3 = field.mod(t3 + z3)
127
- z3 = field.mod(t0 + t0)
128
- t0 = field.mod(z3 + t0)
129
- t0 = field.mod(t0 + t2)
130
- t0 = field.mod(t0 * t3)
131
- y3 = field.mod(y3 + t0)
132
- t2 = field.mod(point.y * point.z)
133
- t2 = field.mod(t2 + t2)
134
- t0 = field.mod(t2 * t3)
135
- x3 = field.mod(x3 - t0)
136
- z3 = field.mod(t2 * t1)
137
- z3 = field.mod(z3 + z3)
138
- z3 = field.mod(z3 + z3)
139
- ProjectivePoint.new(point.group, x3, y3, z3)
140
- end
141
- end
142
- end
143
- end