x25519 0.2.0 → 1.0.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
  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