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 +4 -4
- data/CHANGES.md +10 -0
- data/README.md +3 -1
- data/ext/x25519_precomputed/x25519_precomputed.c +11 -9
- data/ext/x25519_ref10/x25519_ref10.c +10 -8
- data/lib/x25519/scalar.rb +4 -4
- data/lib/x25519/test_vectors.rb +38 -0
- data/lib/x25519/version.rb +1 -1
- data/lib/x25519.rb +22 -6
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e14a38927066f9bf0bb89efc17aa433b42d3fbd
|
4
|
+
data.tar.gz: 7ccda465a96b34ada8f593b1461861a72f2ec253
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
10
|
+
static VALUE mX25519_Provider = Qnil;
|
11
|
+
static VALUE mX25519_Provider_Precomputed = Qnil;
|
11
12
|
|
12
|
-
static VALUE
|
13
|
-
static VALUE
|
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
|
-
|
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(
|
23
|
-
rb_define_singleton_method(
|
24
|
-
rb_define_singleton_method(
|
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
|
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
|
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
|
10
|
+
static VALUE mX25519_Provider = Qnil;
|
11
|
+
static VALUE mX25519_Provider_Ref10 = Qnil;
|
11
12
|
|
12
|
-
static VALUE
|
13
|
-
static VALUE
|
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
|
-
|
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(
|
22
|
-
rb_define_singleton_method(
|
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
|
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
|
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
|
-
@
|
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.
|
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.
|
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
|
-
@
|
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
|
data/lib/x25519/version.rb
CHANGED
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.
|
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.
|
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
|