ecdsa_ext 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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