x25519 0.2.0 → 1.0.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
  SHA1:
3
- metadata.gz: 25356788bb752f943f14d47eb09477c80e8831f3
4
- data.tar.gz: c90ad445482d6d376bb957187ba1c01a4ade1c7d
3
+ metadata.gz: 4e14a38927066f9bf0bb89efc17aa433b42d3fbd
4
+ data.tar.gz: 7ccda465a96b34ada8f593b1461861a72f2ec253
5
5
  SHA512:
6
- metadata.gz: e16c1bfd49e7dd844676159714e6145d357259002800a1033b7993c7ac4049e238dba7c5b8aa1bdff12dced90dfc5a5e70caaf054a3f401eed6efdcd9da7d12f
7
- data.tar.gz: 173e2fecb31f6b0bc09287fe9d7b7bba563e2cac1ca8b9877290b86241cd7cbbb0b4c8d20f212c2dfd777327a50ef6ac403966f9babac4ced0c38fddc4bfba60
6
+ metadata.gz: 0540a115042091e9bd19b45db8b44fa3e0453720ed5d03cb0379e217ebe7a75b784df3510118820fe4e5277de369dfb3c095b1bb4f57975aa2876dff3445be39
7
+ data.tar.gz: 3b230f900fac4f7b183b62a7e53c2385b9e7581fc39ded633a8f0e766f68a5f06805421b0c16f7cb38cad14ed430659a4eed845f8cee02ecfab6aa0ef2e0f78e
data/CHANGES.md CHANGED
@@ -1,3 +1,13 @@
1
+ # [1.0.0] (2017-12-12)
2
+
3
+ [1.0.0]: https://github.com/cryptosphere/x25519/compare/v0.2.0...v1.0.0
4
+
5
+ * [#8](https://github.com/cryptosphere/x25519/pull/8)
6
+ Add self-test
7
+
8
+ * [#7](https://github.com/cryptosphere/x25519/pull/7)
9
+ Factor providers into the `X25519::Provider` namespace
10
+
1
11
  # [0.2.0] (2017-12-12)
2
12
 
3
13
  [0.2.0]: https://github.com/cryptosphere/x25519/compare/v0.1.0...v0.2.0
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
- # x25519.rb [![Latest Version][gem-shield]][gem-link] [![Build Status][build-image]][build-link] [![License: LGPL v3][license-image]][license-link]
1
+ # x25519.rb [![Latest Version][gem-shield]][gem-link] [![Build Status][build-image]][build-link] [![Yard Docs][docs-image]][docs-link] [![License: LGPL v3][license-image]][license-link]
2
2
 
3
3
  [gem-shield]: https://badge.fury.io/rb/x25519.svg
4
4
  [gem-link]: https://rubygems.org/gems/x25519
5
5
  [build-image]: https://travis-ci.org/cryptosphere/x25519.svg?branch=master
6
6
  [build-link]: https://travis-ci.org/cryptosphere/x25519
7
+ [docs-image]: https://img.shields.io/badge/yard-docs-blue.svg
8
+ [docs-link]: http://www.rubydoc.info/gems/x25519
7
9
  [license-image]: https://img.shields.io/badge/License-LGPL%20v3-blue.svg
8
10
  [license-link]: https://www.gnu.org/licenses/lgpl-3.0
9
11
 
@@ -7,25 +7,27 @@ the X25519 Diffie-Hellman algorithm
7
7
  #include "x25519_precomputed.h"
8
8
 
9
9
  static VALUE mX25519 = Qnil;
10
- static VALUE mX25519_Precomputed = Qnil;
10
+ static VALUE mX25519_Provider = Qnil;
11
+ static VALUE mX25519_Provider_Precomputed = Qnil;
11
12
 
12
- static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u);
13
- static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar);
13
+ static VALUE mX25519_Provider_Precomputed_scalarmult(VALUE self, VALUE scalar, VALUE montgomery_u);
14
+ static VALUE mX25519_Provider_Precomputed_scalarmult_base(VALUE self, VALUE scalar);
14
15
  static VALUE mX25519_is_available(VALUE self);
15
16
 
16
17
  /* Initialize the x25519_precomputed C extension */
17
18
  void Init_x25519_precomputed()
18
19
  {
19
20
  mX25519 = rb_define_module("X25519");
20
- mX25519_Precomputed = rb_define_module_under(mX25519, "Precomputed");
21
+ mX25519_Provider = rb_define_module_under(mX25519, "Provider");
22
+ mX25519_Provider_Precomputed = rb_define_module_under(mX25519_Provider, "Precomputed");
21
23
 
22
- rb_define_singleton_method(mX25519_Precomputed, "multiply", mX25519_Scalar_multiply, 2);
23
- rb_define_singleton_method(mX25519_Precomputed, "multiply_base", mX25519_Scalar_multiply_base, 1);
24
- rb_define_singleton_method(mX25519_Precomputed, "available?", mX25519_is_available, 0);
24
+ rb_define_singleton_method(mX25519_Provider_Precomputed, "scalarmult", mX25519_Provider_Precomputed_scalarmult, 2);
25
+ rb_define_singleton_method(mX25519_Provider_Precomputed, "scalarmult_base", mX25519_Provider_Precomputed_scalarmult_base, 1);
26
+ rb_define_singleton_method(mX25519_Provider_Precomputed, "available?", mX25519_is_available, 0);
25
27
  }
26
28
 
27
29
  /* Variable-base scalar multiplication */
28
- static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u)
30
+ static VALUE mX25519_Provider_Precomputed_scalarmult(VALUE self, VALUE scalar, VALUE montgomery_u)
29
31
  {
30
32
  /* X25519_KEY ensures inputs are aligned at 32-bytes */
31
33
  X25519_KEY raw_scalar, raw_montgomery_u, product;
@@ -58,7 +60,7 @@ static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_
58
60
  }
59
61
 
60
62
  /* Fixed-base scalar multiplication */
61
- static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar)
63
+ static VALUE mX25519_Provider_Precomputed_scalarmult_base(VALUE self, VALUE scalar)
62
64
  {
63
65
  /* X25519_KEY ensures inputs are aligned at 32-bytes */
64
66
  X25519_KEY raw_scalar, product;
@@ -7,23 +7,25 @@ X25519 Diffie-Hellman algorithm
7
7
  #include "x25519_ref10.h"
8
8
 
9
9
  static VALUE mX25519 = Qnil;
10
- static VALUE mX25519_Ref10 = Qnil;
10
+ static VALUE mX25519_Provider = Qnil;
11
+ static VALUE mX25519_Provider_Ref10 = Qnil;
11
12
 
12
- static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u);
13
- static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar);
13
+ static VALUE mX25519_Provider_Ref10_scalarmult(VALUE self, VALUE scalar, VALUE montgomery_u);
14
+ static VALUE mX25519_Provider_Ref10_scalarmult_base(VALUE self, VALUE scalar);
14
15
 
15
16
  /* Initialize the x25519_ref10 C extension */
16
17
  void Init_x25519_ref10()
17
18
  {
18
19
  mX25519 = rb_define_module("X25519");
19
- mX25519_Ref10 = rb_define_module_under(mX25519, "Ref10");
20
+ mX25519_Provider = rb_define_module_under(mX25519, "Provider");
21
+ mX25519_Provider_Ref10 = rb_define_module_under(mX25519_Provider, "Ref10");
20
22
 
21
- rb_define_singleton_method(mX25519_Ref10, "multiply", mX25519_Scalar_multiply, 2);
22
- rb_define_singleton_method(mX25519_Ref10, "multiply_base", mX25519_Scalar_multiply_base, 1);
23
+ rb_define_singleton_method(mX25519_Provider_Ref10, "scalarmult", mX25519_Provider_Ref10_scalarmult, 2);
24
+ rb_define_singleton_method(mX25519_Provider_Ref10, "scalarmult_base", mX25519_Provider_Ref10_scalarmult_base, 1);
23
25
  }
24
26
 
25
27
  /* Variable-base scalar multiplication */
26
- static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u)
28
+ static VALUE mX25519_Provider_Ref10_scalarmult(VALUE self, VALUE scalar, VALUE montgomery_u)
27
29
  {
28
30
  X25519_KEY product;
29
31
 
@@ -57,7 +59,7 @@ static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_
57
59
  }
58
60
 
59
61
  /* Fixed-base scalar multiplication */
60
- static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar)
62
+ static VALUE mX25519_Provider_Ref10_scalarmult_base(VALUE self, VALUE scalar)
61
63
  {
62
64
  X25519_KEY product;
63
65
 
data/lib/x25519/scalar.rb CHANGED
@@ -16,7 +16,7 @@ module X25519
16
16
  # @param bytes [String] 32-byte random secret scalar
17
17
  def initialize(bytes)
18
18
  X25519.validate_key_bytes(bytes)
19
- @bytes = bytes
19
+ @scalar_bytes = bytes
20
20
  end
21
21
 
22
22
  # Variable-base scalar multiplication a.k.a. Diffie-Hellman
@@ -28,7 +28,7 @@ module X25519
28
28
  # @return [X25519::MontgomeryU] resulting point (i.e. D-H shared secret)
29
29
  def multiply(montgomery_u)
30
30
  raise TypeError, "expected X25519::MontgomeryU, got #{montgomery_u}" unless montgomery_u.is_a?(MontgomeryU)
31
- MontgomeryU.new(X25519.provider.multiply(@bytes, montgomery_u.to_bytes))
31
+ MontgomeryU.new(X25519.provider.scalarmult(@scalar_bytes, montgomery_u.to_bytes))
32
32
  end
33
33
  alias diffie_hellman multiply
34
34
 
@@ -37,7 +37,7 @@ module X25519
37
37
  #
38
38
  # @return [X25519::MontgomeryU] resulting point (i.e. public key)
39
39
  def multiply_base
40
- MontgomeryU.new(X25519.provider.multiply_base(@bytes))
40
+ MontgomeryU.new(X25519.provider.scalarmult_base(@scalar_bytes))
41
41
  end
42
42
  alias public_key multiply_base
43
43
 
@@ -45,7 +45,7 @@ module X25519
45
45
  #
46
46
  # @return [String] scalar converted to a bytestring
47
47
  def to_bytes
48
- @bytes
48
+ @scalar_bytes
49
49
  end
50
50
 
51
51
  # String inspection that does not leak the private scalar
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module X25519
4
+ # Known-good inputs and outputs for X25519 functions
5
+ module TestVectors
6
+ # Test vector for variable-base scalar multiplication
7
+ VariableBaseVector = Struct.new(:scalar, :input_coord, :output_coord)
8
+
9
+ # X25519 variable-base test vectors from RFC 7748
10
+ VARIABLE_BASE = [
11
+ VariableBaseVector.new(
12
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
13
+ "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
14
+ "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552"
15
+ ),
16
+ VariableBaseVector.new(
17
+ "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
18
+ "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
19
+ "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957"
20
+ )
21
+ ].freeze
22
+
23
+ # Test vector for fixed-base scalar multiplication
24
+ FixedBaseVector = Struct.new(:scalar, :output_coord)
25
+
26
+ # X25519 fixed-base test vectors, generated via RbNaCl/libsodium
27
+ FIXED_BASE = [
28
+ FixedBaseVector.new(
29
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
30
+ "1c9fd88f45606d932a80c71824ae151d15d73e77de38e8e000852e614fae7019"
31
+ ),
32
+ FixedBaseVector.new(
33
+ "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
34
+ "ff63fe57bfbf43fa3f563628b149af704d3db625369c49983650347a6a71e00e"
35
+ )
36
+ ].freeze
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module X25519
4
- VERSION = "0.2.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/x25519.rb CHANGED
@@ -6,6 +6,7 @@ require "x25519/version"
6
6
 
7
7
  require "x25519/montgomery_u"
8
8
  require "x25519/scalar"
9
+ require "x25519/test_vectors"
9
10
 
10
11
  # Native extension backends
11
12
  require "x25519_ref10"
@@ -18,14 +19,13 @@ module X25519
18
19
  # Size of an X25519 key (public or private) in bytes
19
20
  KEY_SIZE = 32
20
21
 
22
+ # ref10 is the default provider
23
+ @provider = X25519::Provider::Ref10
24
+
21
25
  # X25519::Precomputed requires a 4th generation Intel Core CPU or newer,
22
26
  # so only enable it if we detect we're on a supported platform. Otherwise,
23
27
  # fall back to the ref10 portable C implementation.
24
- @provider = if X25519::Precomputed.available?
25
- X25519::Precomputed
26
- else
27
- X25519::Ref10
28
- end
28
+ @provider = X25519::Provider::Precomputed if X25519::Provider::Precomputed.available?
29
29
 
30
30
  # Selected provider based on the logic above
31
31
  def provider
@@ -42,7 +42,7 @@ module X25519
42
42
  def diffie_hellman(scalar_bytes, montgomery_u_bytes)
43
43
  validate_key_bytes(scalar_bytes)
44
44
  validate_key_bytes(montgomery_u_bytes)
45
- X25519.provider.multiply(scalar_bytes, montgomery_u_bytes)
45
+ X25519.provider.scalarmult(scalar_bytes, montgomery_u_bytes)
46
46
  end
47
47
 
48
48
  # Ensure a serialized key meets the requirements
@@ -51,4 +51,20 @@ module X25519
51
51
  return true if key_bytes.bytesize == KEY_SIZE
52
52
  raise ArgumentError, "expected #{KEY_SIZE}-byte String, got #{key_bytes.bytesize}"
53
53
  end
54
+
55
+ # Perform a self-test to ensure the selected provider is working
56
+ def self_test
57
+ X25519::TestVectors::VARIABLE_BASE.each do |v|
58
+ shared_secret = provider.scalarmult([v.scalar].pack("H*"), [v.input_coord].pack("H*"))
59
+ raise "self test failed!" unless shared_secret.unpack("H*").first == v.output_coord
60
+ end
61
+
62
+ X25519::TestVectors::FIXED_BASE.each do |v|
63
+ public_key = provider.scalarmult_base([v.scalar].pack("H*"))
64
+ raise "self test failed!" unless public_key.unpack("H*").first == v.output_coord
65
+ end
66
+ end
54
67
  end
68
+
69
+ # Automatically run self-test when library loads
70
+ X25519.self_test
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: x25519
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
@@ -77,6 +77,7 @@ files:
77
77
  - lib/x25519.rb
78
78
  - lib/x25519/montgomery_u.rb
79
79
  - lib/x25519/scalar.rb
80
+ - lib/x25519/test_vectors.rb
80
81
  - lib/x25519/version.rb
81
82
  - x25519.gemspec
82
83
  homepage: https://github.com/cryptosphere/x25519