ecdsa_ext 0.3.3 → 0.4.1
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 +4 -4
- data/README.md +10 -1
- data/lib/ecdsa/ext/abstract_point.rb +1 -2
- data/lib/ecdsa/ext/jacobian_point.rb +17 -6
- data/lib/ecdsa/ext/projective_point.rb +9 -3
- data/lib/ecdsa/ext/sign_verify.rb +76 -0
- data/lib/ecdsa/ext/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 125f4595851c77d460e1edfa38919c125aa3c06fc469135fc1ba5fe16191a760
|
4
|
+
data.tar.gz: 609d0345ac21dde9f6274db647b7fac1c4a3c9a45cc7fe7a9b9864605cf1b01d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e38986f4f0ecd76a1ab4ac495e1e1d745bbdb0ccb66d81a672e3d8331b8a47b5d4fc726ea716d2f50db6ae91cbe09ed89a01e5bc612fe7467b5485e2adad7326
|
7
|
+
data.tar.gz: 15d1f967986650ce026dc8e6bec695035d2002f69238f96db1324b4ffe736d1adbe653ee1d3c90f4bd67e80a69fdf47d65b6f39f2f4c9fcb3e103dce542c1fab
|
data/README.md
CHANGED
@@ -82,4 +82,13 @@ affine_point = projective_point4.to_affine
|
|
82
82
|
Jacobian coordinates have been supported since 0.3.0.
|
83
83
|
|
84
84
|
When using Jacobian coordinates, use `ECDSA::Ext::JacobianPoint` instead of `ECDSA::Ext::ProjectivePoint`.
|
85
|
-
In addition, `ECDSA::Point` now has a `to_jacobian` method that convert affine coordinates to jacobian coordinates.
|
85
|
+
In addition, `ECDSA::Point` now has a `to_jacobian` method that convert affine coordinates to jacobian coordinates.
|
86
|
+
|
87
|
+
### Apply jacobian coordinates to existing ECDSA sign/verify
|
88
|
+
|
89
|
+
If you want the existing ECDSA gem to generate and verify signatures in Jacobian coordinates,
|
90
|
+
add the following code. This code is a monkey patch to do the existing process in Jacobian coordinates.
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
require 'ecdsa/ext/sign_verify'
|
94
|
+
```
|
@@ -28,14 +28,25 @@ module ECDSA
|
|
28
28
|
return self if other.y.zero? || other.z.zero?
|
29
29
|
|
30
30
|
unless x == other.x
|
31
|
-
|
32
|
-
|
31
|
+
new_point =
|
32
|
+
if z == other.z
|
33
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
|
34
48
|
)
|
35
|
-
|
36
|
-
return add_with_z2_one(other, self) if z == 1
|
37
|
-
return add_with_z2_one(self, other) if other.z == 1
|
38
|
-
return add_with_z_ne(self, other)
|
49
|
+
)
|
39
50
|
end
|
40
51
|
|
41
52
|
return double if self == other
|
@@ -25,12 +25,18 @@ module ECDSA
|
|
25
25
|
end
|
26
26
|
|
27
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
|
28
34
|
return(
|
29
35
|
(
|
30
|
-
if
|
31
|
-
|
36
|
+
if new_point.y.zero? || new_point.z.zero?
|
37
|
+
JacobianPoint.infinity_point(group)
|
32
38
|
else
|
33
|
-
|
39
|
+
new_point
|
34
40
|
end
|
35
41
|
)
|
36
42
|
)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A monkey patch to allow signature generation and verification of existing ECDSA with Jacobian coordinates.
|
4
|
+
module ECDSA
|
5
|
+
def self.sign(group, private_key, digest, temporary_key)
|
6
|
+
# Second part of step 1: Select ephemeral elliptic curve key pair
|
7
|
+
# temporary_key was already selected for us by the caller
|
8
|
+
r_point = (group.generator.to_jacobian * temporary_key).to_affine
|
9
|
+
|
10
|
+
# Steps 2 and 3
|
11
|
+
point_field = PrimeField.new(group.order)
|
12
|
+
r = point_field.mod(r_point.x)
|
13
|
+
return nil if r.zero?
|
14
|
+
|
15
|
+
# Step 4, calculating the hash, was already performed by the caller.
|
16
|
+
|
17
|
+
# Step 5
|
18
|
+
e = normalize_digest(digest, group.bit_length)
|
19
|
+
|
20
|
+
# Step 6
|
21
|
+
s =
|
22
|
+
point_field.mod(
|
23
|
+
point_field.inverse(temporary_key) * (e + r * private_key)
|
24
|
+
)
|
25
|
+
return nil if s.zero?
|
26
|
+
|
27
|
+
Signature.new r, s
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.check_signature!(public_key, digest, signature)
|
31
|
+
group = public_key.group
|
32
|
+
field = group.field
|
33
|
+
|
34
|
+
# Step 1: r and s must be in the field and non-zero
|
35
|
+
unless field.include?(signature.r)
|
36
|
+
raise InvalidSignatureError, "Invalid signature: r is not in the field."
|
37
|
+
end
|
38
|
+
unless field.include?(signature.s)
|
39
|
+
raise InvalidSignatureError, "Invalid signature: s is not in the field."
|
40
|
+
end
|
41
|
+
if signature.r.zero?
|
42
|
+
raise InvalidSignatureError, "Invalid signature: r is zero."
|
43
|
+
end
|
44
|
+
if signature.s.zero?
|
45
|
+
raise InvalidSignatureError, "Invalid signature: s is zero."
|
46
|
+
end
|
47
|
+
|
48
|
+
# Step 2 was already performed when the digest of the message was computed.
|
49
|
+
|
50
|
+
# Step 3: Convert octet string to number and take leftmost bits.
|
51
|
+
e = normalize_digest(digest, group.bit_length)
|
52
|
+
|
53
|
+
# Step 4
|
54
|
+
point_field = PrimeField.new(group.order)
|
55
|
+
s_inverted = point_field.inverse(signature.s)
|
56
|
+
u1 = point_field.mod(e * s_inverted)
|
57
|
+
u2 = point_field.mod(signature.r * s_inverted)
|
58
|
+
|
59
|
+
# Step 5
|
60
|
+
r =
|
61
|
+
(group.generator.to_jacobian * u1 + public_key.to_jacobian * u2).to_affine
|
62
|
+
if r.infinity?
|
63
|
+
raise InvalidSignatureError, "Invalid signature: r is infinity in step 5."
|
64
|
+
end
|
65
|
+
|
66
|
+
# Steps 6 and 7
|
67
|
+
v = point_field.mod r.x
|
68
|
+
|
69
|
+
# Step 8
|
70
|
+
if v != signature.r
|
71
|
+
raise InvalidSignatureError, "Invalid signature: v does not equal r."
|
72
|
+
end
|
73
|
+
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
data/lib/ecdsa/ext/version.rb
CHANGED
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
|
+
version: 0.4.1
|
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-
|
11
|
+
date: 2023-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/ecdsa/ext/point.rb
|
53
53
|
- lib/ecdsa/ext/projective_arithmetic.rb
|
54
54
|
- lib/ecdsa/ext/projective_point.rb
|
55
|
+
- lib/ecdsa/ext/sign_verify.rb
|
55
56
|
- lib/ecdsa/ext/version.rb
|
56
57
|
- lib/ecdsa_ext.rb
|
57
58
|
- sig/ecdsa_ext.rbs
|