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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14a1e1194f60d4d1bbd5d82d77c0d628b76fe3e9ed2efd9dccd5b213fd0506c1
4
- data.tar.gz: 5f832b9a184acb52c59dece9f2db7fef06ba1535e118957100c36ba0895718b0
3
+ metadata.gz: 125f4595851c77d460e1edfa38919c125aa3c06fc469135fc1ba5fe16191a760
4
+ data.tar.gz: 609d0345ac21dde9f6274db647b7fac1c4a3c9a45cc7fe7a9b9864605cf1b01d
5
5
  SHA512:
6
- metadata.gz: 8ea53f7ce5d08ce1766ec5ed7b9030416fb4bb70b9de4db9918656d66869fd1f7c36cff4f06e35bb5aece48e8e0f2ca8a292346b43a30c82c1115196a0d37e7b
7
- data.tar.gz: c7fd59188a641436c3878254299487bd8369565f72625aeb376ae058d9c728b091109ac6b6c87c830ae2f743dba1edcb02a193a29e6ff93c1d37b1d3b084f53f
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
+ ```
@@ -41,9 +41,8 @@ module ECDSA
41
41
  end
42
42
 
43
43
  # Create infinity point
44
- # @return [ECDSA::Ext::JacobianPoint]
44
+ # @return [ECDSA::Ext::AbstractPoint]
45
45
  def self.infinity_point(group)
46
- # new(group, :infinity)
47
46
  new(group, :infinity)
48
47
  end
49
48
 
@@ -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
- if z == other.z
32
- return(
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
- end
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 group.param_a == field.mod(-3)
31
- addition_negative3(self, other)
36
+ if new_point.y.zero? || new_point.z.zero?
37
+ JacobianPoint.infinity_point(group)
32
38
  else
33
- addition_any(self, other)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ECDSA
4
4
  module Ext
5
- VERSION = "0.3.3"
5
+ VERSION = "0.4.1"
6
6
  end
7
7
  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.3.3
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-07 00:00:00.000000000 Z
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