x25519 0.1.0 → 0.2.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 +7 -0
- data/Rakefile +4 -2
- data/ext/{x25519 → x25519_precomputed}/cputest.c +0 -0
- data/ext/x25519_precomputed/extconf.rb +9 -0
- data/ext/{x25519/rfc7748_precomputed → x25519_precomputed}/fp25519_x64.c +0 -0
- data/ext/{x25519/rfc7748_precomputed → x25519_precomputed}/fp25519_x64.h +0 -0
- data/ext/{x25519/rfc7748_precomputed → x25519_precomputed}/table_ladder_x25519.h +0 -0
- data/ext/x25519_precomputed/x25519_precomputed.c +86 -0
- data/ext/{x25519/rfc7748_precomputed/rfc7748_precomputed.h → x25519_precomputed/x25519_precomputed.h} +4 -0
- data/ext/{x25519/rfc7748_precomputed → x25519_precomputed}/x25519_x64.c +3 -3
- data/ext/{x25519/ref10 → x25519_ref10}/api.h +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/base.c +1 -4
- data/ext/x25519_ref10/extconf.rb +9 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe.h +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_0.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_1.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_add.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_copy.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_cswap.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_frombytes.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_invert.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_mul.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_mul121666.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_sq.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_sub.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/fe_tobytes.c +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/montgomery.h +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/pow225521.h +0 -0
- data/ext/{x25519/ref10 → x25519_ref10}/scalarmult.c +1 -0
- data/ext/x25519_ref10/x25519_ref10.c +80 -0
- data/ext/x25519_ref10/x25519_ref10.h +15 -0
- data/lib/x25519.rb +54 -0
- data/lib/x25519/montgomery_u.rb +29 -0
- data/lib/x25519/scalar.rb +56 -0
- data/lib/x25519/version.rb +5 -0
- data/x25519.gemspec +7 -3
- metadata +38 -31
- data/ext/x25519/extconf.rb +0 -31
- data/ext/x25519/x25519.c +0 -325
- data/ext/x25519/x25519.h +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25356788bb752f943f14d47eb09477c80e8831f3
|
4
|
+
data.tar.gz: c90ad445482d6d376bb957187ba1c01a4ade1c7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e16c1bfd49e7dd844676159714e6145d357259002800a1033b7993c7ac4049e238dba7c5b8aa1bdff12dced90dfc5a5e70caaf054a3f401eed6efdcd9da7d12f
|
7
|
+
data.tar.gz: 173e2fecb31f6b0bc09287fe9d7b7bba563e2cac1ca8b9877290b86241cd7cbbb0b4c8d20f212c2dfd777327a50ef6ac403966f9babac4ced0c38fddc4bfba60
|
data/CHANGES.md
CHANGED
data/Rakefile
CHANGED
@@ -6,8 +6,10 @@ require "rake/clean"
|
|
6
6
|
CLEAN.include("**/*.o", "**/*.so", "**/*.bundle", "pkg", "tmp")
|
7
7
|
|
8
8
|
require "rake/extensiontask"
|
9
|
-
|
10
|
-
|
9
|
+
%w[precomputed ref10].each do |provider|
|
10
|
+
Rake::ExtensionTask.new("x25519_#{provider}") do |ext|
|
11
|
+
ext.ext_dir = "ext/x25519_#{provider}"
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
require "rspec/core/rake_task"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,86 @@
|
|
1
|
+
/*
|
2
|
+
Ruby C extension providing bindings to the rfc7748_precomputed implementation of
|
3
|
+
the X25519 Diffie-Hellman algorithm
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "x25519_precomputed.h"
|
8
|
+
|
9
|
+
static VALUE mX25519 = Qnil;
|
10
|
+
static VALUE mX25519_Precomputed = Qnil;
|
11
|
+
|
12
|
+
static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u);
|
13
|
+
static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar);
|
14
|
+
static VALUE mX25519_is_available(VALUE self);
|
15
|
+
|
16
|
+
/* Initialize the x25519_precomputed C extension */
|
17
|
+
void Init_x25519_precomputed()
|
18
|
+
{
|
19
|
+
mX25519 = rb_define_module("X25519");
|
20
|
+
mX25519_Precomputed = rb_define_module_under(mX25519, "Precomputed");
|
21
|
+
|
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);
|
25
|
+
}
|
26
|
+
|
27
|
+
/* Variable-base scalar multiplication */
|
28
|
+
static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u)
|
29
|
+
{
|
30
|
+
/* X25519_KEY ensures inputs are aligned at 32-bytes */
|
31
|
+
X25519_KEY raw_scalar, raw_montgomery_u, product;
|
32
|
+
|
33
|
+
StringValue(scalar);
|
34
|
+
if(RSTRING_LEN(scalar) != X25519_KEYSIZE_BYTES) {
|
35
|
+
rb_raise(
|
36
|
+
rb_eArgError,
|
37
|
+
"expected %d-byte scalar, got %ld",
|
38
|
+
X25519_KEYSIZE_BYTES,
|
39
|
+
RSTRING_LEN(scalar)
|
40
|
+
);
|
41
|
+
}
|
42
|
+
|
43
|
+
StringValue(montgomery_u);
|
44
|
+
if(RSTRING_LEN(montgomery_u) != X25519_KEYSIZE_BYTES) {
|
45
|
+
rb_raise(
|
46
|
+
rb_eArgError,
|
47
|
+
"expected %d-byte Montgomery-u coordinate, got %ld",
|
48
|
+
X25519_KEYSIZE_BYTES,
|
49
|
+
RSTRING_LEN(montgomery_u)
|
50
|
+
);
|
51
|
+
}
|
52
|
+
|
53
|
+
memcpy(raw_scalar, RSTRING_PTR(scalar), X25519_KEYSIZE_BYTES);
|
54
|
+
memcpy(raw_montgomery_u, RSTRING_PTR(montgomery_u), X25519_KEYSIZE_BYTES);
|
55
|
+
x25519_precomputed_scalarmult(product, raw_scalar, raw_montgomery_u);
|
56
|
+
|
57
|
+
return rb_str_new((const char *)product, X25519_KEYSIZE_BYTES);
|
58
|
+
}
|
59
|
+
|
60
|
+
/* Fixed-base scalar multiplication */
|
61
|
+
static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar)
|
62
|
+
{
|
63
|
+
/* X25519_KEY ensures inputs are aligned at 32-bytes */
|
64
|
+
X25519_KEY raw_scalar, product;
|
65
|
+
|
66
|
+
StringValue(scalar);
|
67
|
+
if(RSTRING_LEN(scalar) != X25519_KEYSIZE_BYTES) {
|
68
|
+
rb_raise(
|
69
|
+
rb_eArgError,
|
70
|
+
"expected %d-byte scalar, got %ld",
|
71
|
+
X25519_KEYSIZE_BYTES,
|
72
|
+
RSTRING_LEN(scalar)
|
73
|
+
);
|
74
|
+
}
|
75
|
+
|
76
|
+
memcpy(raw_scalar, RSTRING_PTR(scalar), X25519_KEYSIZE_BYTES);
|
77
|
+
x25519_precomputed_scalarmult_base(product, raw_scalar);
|
78
|
+
|
79
|
+
return rb_str_new((const char *)product, X25519_KEYSIZE_BYTES);
|
80
|
+
}
|
81
|
+
|
82
|
+
/* Is the x25519_precomputed backend supported on this CPU? */
|
83
|
+
static VALUE mX25519_is_available(VALUE self)
|
84
|
+
{
|
85
|
+
return check_4th_gen_intel_core_features() ? Qtrue : Qfalse;
|
86
|
+
}
|
@@ -30,4 +30,8 @@
|
|
30
30
|
#define X25519_KEYSIZE_BYTES 32
|
31
31
|
typedef ALIGN uint8_t X25519_KEY[X25519_KEYSIZE_BYTES];
|
32
32
|
|
33
|
+
void x25519_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key, uint8_t *session_key);
|
34
|
+
void x25519_precomputed_scalarmult_base(uint8_t *session_key, uint8_t *private_key);
|
35
|
+
int check_4th_gen_intel_core_features();
|
36
|
+
|
33
37
|
#endif /* RFC7748_PRECOMPUTED_H */
|
@@ -17,7 +17,7 @@
|
|
17
17
|
*/
|
18
18
|
#include "fp25519_x64.h"
|
19
19
|
#include "table_ladder_x25519.h"
|
20
|
-
#include "
|
20
|
+
#include "x25519_precomputed.h"
|
21
21
|
|
22
22
|
/****** Implementation of Montgomery Ladder Algorithm ************/
|
23
23
|
static inline void cswap_x64(uint64_t bit, uint64_t *const px, uint64_t *const py)
|
@@ -32,7 +32,7 @@ static inline void cswap_x64(uint64_t bit, uint64_t *const px, uint64_t *const p
|
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
35
|
-
void
|
35
|
+
void x25519_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key, uint8_t *session_key)
|
36
36
|
{
|
37
37
|
ALIGN uint64_t buffer[4*NUM_WORDS_ELTFP25519_X64];
|
38
38
|
ALIGN uint64_t coordinates[4*NUM_WORDS_ELTFP25519_X64];
|
@@ -133,7 +133,7 @@ void x25519_rfc7748_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key
|
|
133
133
|
private_key[0] = (uint8_t)(save & 0xFF);
|
134
134
|
}
|
135
135
|
|
136
|
-
void
|
136
|
+
void x25519_precomputed_scalarmult_base(uint8_t *session_key, uint8_t *private_key)
|
137
137
|
{
|
138
138
|
ALIGN uint64_t buffer[4*NUM_WORDS_ELTFP25519_X64];
|
139
139
|
ALIGN uint64_t coordinates[4*NUM_WORDS_ELTFP25519_X64];
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,80 @@
|
|
1
|
+
/*
|
2
|
+
Ruby C extension providing bindings to the ref10 implementation of the
|
3
|
+
X25519 Diffie-Hellman algorithm
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "x25519_ref10.h"
|
8
|
+
|
9
|
+
static VALUE mX25519 = Qnil;
|
10
|
+
static VALUE mX25519_Ref10 = Qnil;
|
11
|
+
|
12
|
+
static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u);
|
13
|
+
static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar);
|
14
|
+
|
15
|
+
/* Initialize the x25519_ref10 C extension */
|
16
|
+
void Init_x25519_ref10()
|
17
|
+
{
|
18
|
+
mX25519 = rb_define_module("X25519");
|
19
|
+
mX25519_Ref10 = rb_define_module_under(mX25519, "Ref10");
|
20
|
+
|
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
|
+
}
|
24
|
+
|
25
|
+
/* Variable-base scalar multiplication */
|
26
|
+
static VALUE mX25519_Scalar_multiply(VALUE self, VALUE scalar, VALUE montgomery_u)
|
27
|
+
{
|
28
|
+
X25519_KEY product;
|
29
|
+
|
30
|
+
StringValue(scalar);
|
31
|
+
if(RSTRING_LEN(scalar) != X25519_KEYSIZE_BYTES) {
|
32
|
+
rb_raise(
|
33
|
+
rb_eArgError,
|
34
|
+
"expected %d-byte scalar, got %ld",
|
35
|
+
X25519_KEYSIZE_BYTES,
|
36
|
+
RSTRING_LEN(scalar)
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
StringValue(montgomery_u);
|
41
|
+
if(RSTRING_LEN(montgomery_u) != X25519_KEYSIZE_BYTES) {
|
42
|
+
rb_raise(
|
43
|
+
rb_eArgError,
|
44
|
+
"expected %d-byte Montgomery-u coordinate, got %ld",
|
45
|
+
X25519_KEYSIZE_BYTES,
|
46
|
+
RSTRING_LEN(montgomery_u)
|
47
|
+
);
|
48
|
+
}
|
49
|
+
|
50
|
+
x25519_ref10_scalarmult(
|
51
|
+
product,
|
52
|
+
(const uint8_t *)RSTRING_PTR(scalar),
|
53
|
+
(const uint8_t *)RSTRING_PTR(montgomery_u)
|
54
|
+
);
|
55
|
+
|
56
|
+
return rb_str_new((const char *)product, X25519_KEYSIZE_BYTES);
|
57
|
+
}
|
58
|
+
|
59
|
+
/* Fixed-base scalar multiplication */
|
60
|
+
static VALUE mX25519_Scalar_multiply_base(VALUE self, VALUE scalar)
|
61
|
+
{
|
62
|
+
X25519_KEY product;
|
63
|
+
|
64
|
+
StringValue(scalar);
|
65
|
+
if(RSTRING_LEN(scalar) != X25519_KEYSIZE_BYTES) {
|
66
|
+
rb_raise(
|
67
|
+
rb_eArgError,
|
68
|
+
"expected %d-byte scalar, got %ld",
|
69
|
+
X25519_KEYSIZE_BYTES,
|
70
|
+
RSTRING_LEN(scalar)
|
71
|
+
);
|
72
|
+
}
|
73
|
+
|
74
|
+
x25519_ref10_scalarmult_base(
|
75
|
+
product,
|
76
|
+
(const uint8_t *)RSTRING_PTR(scalar)
|
77
|
+
);
|
78
|
+
|
79
|
+
return rb_str_new((const char *)product, X25519_KEYSIZE_BYTES);
|
80
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef RFC7748_REF10_H
|
2
|
+
#define RFC7748_REF10_H
|
3
|
+
|
4
|
+
#include <stdint.h>
|
5
|
+
|
6
|
+
#define X25519_KEYSIZE_BYTES 32
|
7
|
+
typedef uint8_t X25519_KEY[X25519_KEYSIZE_BYTES];
|
8
|
+
|
9
|
+
/* Fixed-base scalar multiplication */
|
10
|
+
int x25519_ref10_scalarmult(uint8_t *q, const uint8_t *n, const uint8_t *p);
|
11
|
+
|
12
|
+
/* Variable-base scalar multiplication */
|
13
|
+
int x25519_ref10_scalarmult_base(uint8_t *q, const uint8_t *n);
|
14
|
+
|
15
|
+
#endif /* RFC7748_REF10_H */
|
data/lib/x25519.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
require "x25519/version"
|
6
|
+
|
7
|
+
require "x25519/montgomery_u"
|
8
|
+
require "x25519/scalar"
|
9
|
+
|
10
|
+
# Native extension backends
|
11
|
+
require "x25519_ref10"
|
12
|
+
require "x25519_precomputed"
|
13
|
+
|
14
|
+
# The X25519 elliptic curve Diffie-Hellman algorithm
|
15
|
+
module X25519
|
16
|
+
module_function
|
17
|
+
|
18
|
+
# Size of an X25519 key (public or private) in bytes
|
19
|
+
KEY_SIZE = 32
|
20
|
+
|
21
|
+
# X25519::Precomputed requires a 4th generation Intel Core CPU or newer,
|
22
|
+
# so only enable it if we detect we're on a supported platform. Otherwise,
|
23
|
+
# fall back to the ref10 portable C implementation.
|
24
|
+
@provider = if X25519::Precomputed.available?
|
25
|
+
X25519::Precomputed
|
26
|
+
else
|
27
|
+
X25519::Ref10
|
28
|
+
end
|
29
|
+
|
30
|
+
# Selected provider based on the logic above
|
31
|
+
def provider
|
32
|
+
@provider
|
33
|
+
end
|
34
|
+
|
35
|
+
# Raw Diffie-Hellman function that acts directly on bytestrings. An
|
36
|
+
# alternative to the object-oriented API
|
37
|
+
#
|
38
|
+
# @param scalar_bytes [String] a serialized private scalar
|
39
|
+
# @param montgomery_u_bytes [String] a point we wish to multiply by the scalar
|
40
|
+
#
|
41
|
+
# @return [String] resulting point, serialized as bytes
|
42
|
+
def diffie_hellman(scalar_bytes, montgomery_u_bytes)
|
43
|
+
validate_key_bytes(scalar_bytes)
|
44
|
+
validate_key_bytes(montgomery_u_bytes)
|
45
|
+
X25519.provider.multiply(scalar_bytes, montgomery_u_bytes)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Ensure a serialized key meets the requirements
|
49
|
+
def validate_key_bytes(key_bytes)
|
50
|
+
raise TypeError, "expected String, got #{key_bytes.class}" unless key_bytes.is_a?(String)
|
51
|
+
return true if key_bytes.bytesize == KEY_SIZE
|
52
|
+
raise ArgumentError, "expected #{KEY_SIZE}-byte String, got #{key_bytes.bytesize}"
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module X25519
|
4
|
+
# X25519 public keys and shared secrets
|
5
|
+
#
|
6
|
+
# Montgomery-u coordinates of points on the elliptic curve used by X25519
|
7
|
+
# (a.k.a. Curve25519)
|
8
|
+
class MontgomeryU
|
9
|
+
# Create an object representing a Montgomery-u coordinate from a bytestring
|
10
|
+
#
|
11
|
+
# @param bytes [String] 32-byte compressed Montgomery-u coordinate
|
12
|
+
def initialize(bytes)
|
13
|
+
X25519.validate_key_bytes(bytes)
|
14
|
+
@bytes = bytes
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return a compressed Montgomery-u coordinate serialized as a bytestring
|
18
|
+
#
|
19
|
+
# @return [String] bytestring serialization of a Montgomery-u coordinate
|
20
|
+
def to_bytes
|
21
|
+
@bytes
|
22
|
+
end
|
23
|
+
|
24
|
+
# Show hex representation of serialized coordinate in string inspection
|
25
|
+
def inspect
|
26
|
+
"#<#{self.class}:#{@bytes.unpack('H*').first}>"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module X25519
|
4
|
+
# X25519 private keys
|
5
|
+
#
|
6
|
+
# Scalars are the integer component of scalar multiplication, multiplied
|
7
|
+
# against an elliptic curve point.
|
8
|
+
class Scalar
|
9
|
+
# Securely generate a random scalar
|
10
|
+
def self.generate
|
11
|
+
new(SecureRandom.random_bytes(X25519::KEY_SIZE))
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create an X25519 scalar object from a bytestring
|
15
|
+
#
|
16
|
+
# @param bytes [String] 32-byte random secret scalar
|
17
|
+
def initialize(bytes)
|
18
|
+
X25519.validate_key_bytes(bytes)
|
19
|
+
@bytes = bytes
|
20
|
+
end
|
21
|
+
|
22
|
+
# Variable-base scalar multiplication a.k.a. Diffie-Hellman
|
23
|
+
#
|
24
|
+
# This can be used to obtain a shared secret from a public key
|
25
|
+
#
|
26
|
+
# @param montgomery_u [X25519::MontgomeryU] coordinate of the public key/point to perform D-H with
|
27
|
+
#
|
28
|
+
# @return [X25519::MontgomeryU] resulting point (i.e. D-H shared secret)
|
29
|
+
def multiply(montgomery_u)
|
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))
|
32
|
+
end
|
33
|
+
alias diffie_hellman multiply
|
34
|
+
|
35
|
+
# Fixed-base scalar multiplication. Calculates a public key from a
|
36
|
+
# private scalar
|
37
|
+
#
|
38
|
+
# @return [X25519::MontgomeryU] resulting point (i.e. public key)
|
39
|
+
def multiply_base
|
40
|
+
MontgomeryU.new(X25519.provider.multiply_base(@bytes))
|
41
|
+
end
|
42
|
+
alias public_key multiply_base
|
43
|
+
|
44
|
+
# Return a bytestring representation of this scalar
|
45
|
+
#
|
46
|
+
# @return [String] scalar converted to a bytestring
|
47
|
+
def to_bytes
|
48
|
+
@bytes
|
49
|
+
end
|
50
|
+
|
51
|
+
# String inspection that does not leak the private scalar
|
52
|
+
def inspect
|
53
|
+
to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/x25519.gemspec
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "x25519/version"
|
6
|
+
|
3
7
|
Gem::Specification.new do |spec|
|
4
8
|
spec.name = "x25519"
|
5
|
-
spec.version =
|
9
|
+
spec.version = X25519::VERSION
|
6
10
|
spec.authors = ["Tony Arcieri"]
|
7
11
|
spec.email = ["bascule@gmail.com"]
|
8
12
|
spec.summary = "Public key cryptography library providing the X25519 D-H function"
|
9
13
|
spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
10
14
|
An efficient public key cryptography library for Ruby providing key
|
11
15
|
exchange/agreement via the X25519 (a.k.a. Curve25519) Elliptic Curve
|
12
|
-
Diffie-Hellman function as described in
|
16
|
+
Diffie-Hellman function as described in RFC 7748.
|
13
17
|
DESCRIPTION
|
14
18
|
spec.homepage = "https://github.com/cryptosphere/x25519"
|
15
19
|
spec.license = "MIT"
|
@@ -18,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
18
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
23
|
spec.require_paths = ["lib"]
|
20
24
|
spec.platform = Gem::Platform::RUBY
|
21
|
-
spec.extensions = "ext/
|
25
|
+
spec.extensions = ["ext/x25519_precomputed/extconf.rb", "ext/x25519_ref10/extconf.rb"]
|
22
26
|
|
23
27
|
spec.required_ruby_version = ">= 2.2.2"
|
24
28
|
spec.add_development_dependency "bundler", "~> 1.16"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: x25519
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -26,12 +26,13 @@ dependencies:
|
|
26
26
|
version: '1.16'
|
27
27
|
description: An efficient public key cryptography library for Ruby providing key exchange/agreement
|
28
28
|
via the X25519 (a.k.a. Curve25519) Elliptic Curve Diffie-Hellman function as described
|
29
|
-
in
|
29
|
+
in RFC 7748.
|
30
30
|
email:
|
31
31
|
- bascule@gmail.com
|
32
32
|
executables: []
|
33
33
|
extensions:
|
34
|
-
- ext/
|
34
|
+
- ext/x25519_precomputed/extconf.rb
|
35
|
+
- ext/x25519_ref10/extconf.rb
|
35
36
|
extra_rdoc_files: []
|
36
37
|
files:
|
37
38
|
- ".gitignore"
|
@@ -44,33 +45,39 @@ files:
|
|
44
45
|
- LICENSE
|
45
46
|
- README.md
|
46
47
|
- Rakefile
|
47
|
-
- ext/
|
48
|
-
- ext/
|
49
|
-
- ext/
|
50
|
-
- ext/
|
51
|
-
- ext/
|
52
|
-
- ext/
|
53
|
-
- ext/
|
54
|
-
- ext/
|
55
|
-
- ext/
|
56
|
-
- ext/
|
57
|
-
- ext/
|
58
|
-
- ext/
|
59
|
-
- ext/
|
60
|
-
- ext/
|
61
|
-
- ext/
|
62
|
-
- ext/
|
63
|
-
- ext/
|
64
|
-
- ext/
|
65
|
-
- ext/
|
66
|
-
- ext/
|
67
|
-
- ext/
|
68
|
-
- ext/
|
69
|
-
- ext/
|
70
|
-
- ext/
|
71
|
-
- ext/
|
72
|
-
- ext/
|
73
|
-
- ext/
|
48
|
+
- ext/x25519_precomputed/cputest.c
|
49
|
+
- ext/x25519_precomputed/extconf.rb
|
50
|
+
- ext/x25519_precomputed/fp25519_x64.c
|
51
|
+
- ext/x25519_precomputed/fp25519_x64.h
|
52
|
+
- ext/x25519_precomputed/table_ladder_x25519.h
|
53
|
+
- ext/x25519_precomputed/x25519_precomputed.c
|
54
|
+
- ext/x25519_precomputed/x25519_precomputed.h
|
55
|
+
- ext/x25519_precomputed/x25519_x64.c
|
56
|
+
- ext/x25519_ref10/api.h
|
57
|
+
- ext/x25519_ref10/base.c
|
58
|
+
- ext/x25519_ref10/extconf.rb
|
59
|
+
- ext/x25519_ref10/fe.h
|
60
|
+
- ext/x25519_ref10/fe_0.c
|
61
|
+
- ext/x25519_ref10/fe_1.c
|
62
|
+
- ext/x25519_ref10/fe_add.c
|
63
|
+
- ext/x25519_ref10/fe_copy.c
|
64
|
+
- ext/x25519_ref10/fe_cswap.c
|
65
|
+
- ext/x25519_ref10/fe_frombytes.c
|
66
|
+
- ext/x25519_ref10/fe_invert.c
|
67
|
+
- ext/x25519_ref10/fe_mul.c
|
68
|
+
- ext/x25519_ref10/fe_mul121666.c
|
69
|
+
- ext/x25519_ref10/fe_sq.c
|
70
|
+
- ext/x25519_ref10/fe_sub.c
|
71
|
+
- ext/x25519_ref10/fe_tobytes.c
|
72
|
+
- ext/x25519_ref10/montgomery.h
|
73
|
+
- ext/x25519_ref10/pow225521.h
|
74
|
+
- ext/x25519_ref10/scalarmult.c
|
75
|
+
- ext/x25519_ref10/x25519_ref10.c
|
76
|
+
- ext/x25519_ref10/x25519_ref10.h
|
77
|
+
- lib/x25519.rb
|
78
|
+
- lib/x25519/montgomery_u.rb
|
79
|
+
- lib/x25519/scalar.rb
|
80
|
+
- lib/x25519/version.rb
|
74
81
|
- x25519.gemspec
|
75
82
|
homepage: https://github.com/cryptosphere/x25519
|
76
83
|
licenses:
|
data/ext/x25519/extconf.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Style/GlobalVars
|
4
|
-
|
5
|
-
require "mkmf"
|
6
|
-
|
7
|
-
abort("missing posix_memalign()") unless have_func("posix_memalign", "stdlib.h")
|
8
|
-
|
9
|
-
$INCFLAGS << " -I$(srcdir)/ref10 -I$(srcdir)/rfc7748_precomputed"
|
10
|
-
|
11
|
-
# Check for Intel 4th Gen Core CPU features
|
12
|
-
# TODO: move this detection completely to runtime
|
13
|
-
cputest_c = <<SRC
|
14
|
-
#{File.read(File.expand_path('cputest.c', __dir__))}
|
15
|
-
int main() {
|
16
|
-
return check_4th_gen_intel_core_features() != 1;
|
17
|
-
}
|
18
|
-
SRC
|
19
|
-
|
20
|
-
if try_run(cputest_c)
|
21
|
-
$defs.push("-DHAVE_4TH_GEN_INTEL_CORE")
|
22
|
-
$CFLAGS << " -Wall -O3 -pedantic -std=c99 -mbmi -mbmi2 -march=native -mtune=native"
|
23
|
-
$srcs = Dir.glob(File.join(__dir__, "**", "*.c"))
|
24
|
-
else
|
25
|
-
# Do not include the rfc7748_precomputed sources if we do not have a 4th gen+ Core CPU
|
26
|
-
$srcs = Dir.glob(File.join(__dir__, "*.c")) + Dir.glob(File.expand_path("ref10/*.c", __dir__))
|
27
|
-
end
|
28
|
-
|
29
|
-
$objs = $srcs.map { |src| src.sub(/\.c$/, ".o") }
|
30
|
-
|
31
|
-
create_makefile "x25519"
|
data/ext/x25519/x25519.c
DELETED
@@ -1,325 +0,0 @@
|
|
1
|
-
/* Ruby C extension providing bindings to the X25519 Diffie-Hellman algorithm */
|
2
|
-
|
3
|
-
#define _POSIX_C_SOURCE 200809L
|
4
|
-
#include <stdlib.h>
|
5
|
-
|
6
|
-
#include "ruby.h"
|
7
|
-
#include "x25519.h"
|
8
|
-
|
9
|
-
/* The X25519::VERSION */
|
10
|
-
#define GEM_VERSION "0.1.0"
|
11
|
-
|
12
|
-
/* X25519 module method prototypes */
|
13
|
-
static VALUE X25519_backend(VALUE self);
|
14
|
-
static VALUE X25519_self_test(VALUE self);
|
15
|
-
static VALUE X25519_diffie_hellman(VALUE self, VALUE public_key, VALUE secret_key);
|
16
|
-
|
17
|
-
/* X25519::Scalar prototypes */
|
18
|
-
static VALUE cX25519_Scalar_allocate(VALUE klass);
|
19
|
-
static void cX25519_Scalar_mark(X25519_KEY *scalar);
|
20
|
-
static void cX25519_Scalar_free(X25519_KEY *scalar);
|
21
|
-
static VALUE cX25519_Scalar_generate(VALUE self);
|
22
|
-
static VALUE cX25519_Scalar_initialize(VALUE self, VALUE bytes);
|
23
|
-
static VALUE cX25519_Scalar_multiply_base(VALUE self);
|
24
|
-
static VALUE cX25519_Scalar_multiply(VALUE self, VALUE montgomery_u);
|
25
|
-
static VALUE cX25519_Scalar_to_bytes(VALUE self);
|
26
|
-
|
27
|
-
/* X25519::MontgomeryU prototypes */
|
28
|
-
static VALUE cX25519_MontgomeryU_allocate(VALUE klass);
|
29
|
-
static void cX25519_MontgomeryU_mark(X25519_KEY *coord);
|
30
|
-
static void cX25519_MontgomeryU_free(X25519_KEY *coord);
|
31
|
-
static VALUE cX25519_MontgomeryU_initialize(VALUE self, VALUE bytes);
|
32
|
-
static VALUE cX25519_MontgomeryU_to_bytes(VALUE self);
|
33
|
-
|
34
|
-
static VALUE mX25519 = Qnil;
|
35
|
-
static VALUE cX25519_Scalar = Qnil;
|
36
|
-
static VALUE cX25519_MontgomeryU = Qnil;
|
37
|
-
|
38
|
-
/* Are we on a 4th gen Intel Core CPU architecture that supports the
|
39
|
-
rfc7748_precomputed backend? */
|
40
|
-
static int use_rfc7748_precomputed = 0;
|
41
|
-
|
42
|
-
/* Initialize the Ruby module */
|
43
|
-
void Init_x25519()
|
44
|
-
{
|
45
|
-
/* Test for support for the rfc7748_precomputed backend */
|
46
|
-
use_rfc7748_precomputed = check_4th_gen_intel_core_features();
|
47
|
-
|
48
|
-
/* Used for key generation */
|
49
|
-
rb_require("securerandom");
|
50
|
-
|
51
|
-
mX25519 = rb_define_module("X25519");
|
52
|
-
rb_define_const(mX25519, "VERSION", rb_str_new2(GEM_VERSION));
|
53
|
-
rb_define_singleton_method(mX25519, "backend", X25519_backend, 0);
|
54
|
-
rb_define_singleton_method(mX25519, "self_test", X25519_self_test, 0);
|
55
|
-
rb_define_singleton_method(mX25519, "diffie_hellman", X25519_diffie_hellman, 2);
|
56
|
-
|
57
|
-
cX25519_Scalar = rb_define_class_under(mX25519, "Scalar", rb_cObject);
|
58
|
-
rb_define_alloc_func(cX25519_Scalar, cX25519_Scalar_allocate);
|
59
|
-
rb_define_singleton_method(cX25519_Scalar, "generate", cX25519_Scalar_generate, 0);
|
60
|
-
rb_define_method(cX25519_Scalar, "initialize", cX25519_Scalar_initialize, 1);
|
61
|
-
rb_define_method(cX25519_Scalar, "multiply_base", cX25519_Scalar_multiply_base, 0);
|
62
|
-
rb_define_method(cX25519_Scalar, "public_key", cX25519_Scalar_multiply_base, 0);
|
63
|
-
rb_define_method(cX25519_Scalar, "multiply", cX25519_Scalar_multiply, 1);
|
64
|
-
rb_define_method(cX25519_Scalar, "diffie_hellman", cX25519_Scalar_multiply, 1);
|
65
|
-
rb_define_method(cX25519_Scalar, "to_bytes", cX25519_Scalar_to_bytes, 0);
|
66
|
-
rb_define_method(cX25519_Scalar, "to_str", cX25519_Scalar_to_bytes, 0);
|
67
|
-
|
68
|
-
cX25519_MontgomeryU = rb_define_class_under(mX25519, "MontgomeryU", rb_cObject);
|
69
|
-
rb_define_alloc_func(cX25519_MontgomeryU, cX25519_MontgomeryU_allocate);
|
70
|
-
rb_define_method(cX25519_MontgomeryU, "initialize", cX25519_MontgomeryU_initialize, 1);
|
71
|
-
rb_define_method(cX25519_MontgomeryU, "to_bytes", cX25519_MontgomeryU_to_bytes, 0);
|
72
|
-
rb_define_method(cX25519_MontgomeryU, "to_str", cX25519_MontgomeryU_to_bytes, 0);
|
73
|
-
|
74
|
-
/* Run the self-test on load to ensure everything is working */
|
75
|
-
rb_funcall(mX25519, rb_intern("self_test"), 0);
|
76
|
-
}
|
77
|
-
|
78
|
-
/* Return a symbol identifying the backend in use */
|
79
|
-
static VALUE X25519_backend(VALUE self)
|
80
|
-
{
|
81
|
-
switch(use_rfc7748_precomputed) {
|
82
|
-
case 1:
|
83
|
-
return ID2SYM(rb_intern("rfc7748_precomputed"));
|
84
|
-
case 0:
|
85
|
-
return ID2SYM(rb_intern("ref10"));
|
86
|
-
default:
|
87
|
-
rb_raise(rb_eRuntimeError, "invalid X25519 backend! (%d)", use_rfc7748_precomputed);
|
88
|
-
}
|
89
|
-
}
|
90
|
-
|
91
|
-
/* Perform an end-to-end test of the Ruby binding to ensure it's working correctly */
|
92
|
-
static VALUE X25519_self_test(VALUE self)
|
93
|
-
{
|
94
|
-
VALUE sk, pk, shared;
|
95
|
-
|
96
|
-
/* Test vectors from RFC 7748 */
|
97
|
-
X25519_KEY ietf_cfrg_key0 = {
|
98
|
-
0xa5,0x46,0xe3,0x6b,0xf0,0x52,0x7c,0x9d,
|
99
|
-
0x3b,0x16,0x15,0x4b,0x82,0x46,0x5e,0xdd,
|
100
|
-
0x62,0x14,0x4c,0x0a,0xc1,0xfc,0x5a,0x18,
|
101
|
-
0x50,0x6a,0x22,0x44,0xba,0x44,0x9a,0xc4
|
102
|
-
};
|
103
|
-
|
104
|
-
X25519_KEY ietf_cfrg_input_coord0 = {
|
105
|
-
0xe6,0xdb,0x68,0x67,0x58,0x30,0x30,0xdb,
|
106
|
-
0x35,0x94,0xc1,0xa4,0x24,0xb1,0x5f,0x7c,
|
107
|
-
0x72,0x66,0x24,0xec,0x26,0xb3,0x35,0x3b,
|
108
|
-
0x10,0xa9,0x03,0xa6,0xd0,0xab,0x1c,0x4c
|
109
|
-
};
|
110
|
-
|
111
|
-
X25519_KEY ietf_cfrg_output_coord0 = {
|
112
|
-
0xc3,0xda,0x55,0x37,0x9d,0xe9,0xc6,0x90,
|
113
|
-
0x8e,0x94,0xea,0x4d,0xf2,0x8d,0x08,0x4f,
|
114
|
-
0x32,0xec,0xcf,0x03,0x49,0x1c,0x71,0xf7,
|
115
|
-
0x54,0xb4,0x07,0x55,0x77,0xa2,0x85,0x52
|
116
|
-
};
|
117
|
-
|
118
|
-
sk = rb_str_new((const char *)&ietf_cfrg_key0, X25519_KEYSIZE_BYTES);
|
119
|
-
pk = rb_str_new((const char *)&ietf_cfrg_input_coord0, X25519_KEYSIZE_BYTES);
|
120
|
-
|
121
|
-
shared = rb_funcall(mX25519, rb_intern("diffie_hellman"), 2, sk, pk);
|
122
|
-
|
123
|
-
if(RSTRING_LEN(shared) != X25519_KEYSIZE_BYTES ||
|
124
|
-
memcmp(RSTRING_PTR(shared), ietf_cfrg_output_coord0, X25519_KEYSIZE_BYTES) != 0)
|
125
|
-
{
|
126
|
-
rb_raise(rb_eRuntimeError, "X25519 self-test failed!");
|
127
|
-
}
|
128
|
-
|
129
|
-
return Qtrue;
|
130
|
-
}
|
131
|
-
|
132
|
-
/* Compute Diffie-Hellman for the given key and Montgomery-u coordinate
|
133
|
-
* (i.e. variable base scalar multiplication) */
|
134
|
-
static VALUE X25519_diffie_hellman(VALUE self, VALUE secret_key, VALUE public_key)
|
135
|
-
{
|
136
|
-
VALUE scalar, coord, shared;
|
137
|
-
|
138
|
-
scalar = rb_class_new_instance(1, &secret_key, cX25519_Scalar);
|
139
|
-
coord = rb_class_new_instance(1, &public_key, cX25519_MontgomeryU);
|
140
|
-
shared = rb_funcall(scalar, rb_intern("multiply"), 1, coord);
|
141
|
-
|
142
|
-
return rb_funcall(shared, rb_intern("to_bytes"), 0);
|
143
|
-
}
|
144
|
-
|
145
|
-
/********************************
|
146
|
-
* X25519::Scalar: private keys *
|
147
|
-
********************************/
|
148
|
-
|
149
|
-
static VALUE cX25519_Scalar_allocate(VALUE klass)
|
150
|
-
{
|
151
|
-
X25519_KEY *scalar = NULL;
|
152
|
-
|
153
|
-
/* Ensure allocation with the correct (32-byte) memory alignent */
|
154
|
-
if(posix_memalign((void **)&scalar, ALIGN_BYTES, X25519_KEYSIZE_BYTES)) {
|
155
|
-
rb_fatal("x25519: can't allocate memory with posix_memalign()");
|
156
|
-
}
|
157
|
-
|
158
|
-
/* Avoid using unitialized memory */
|
159
|
-
memset(scalar, 0, X25519_KEYSIZE_BYTES);
|
160
|
-
|
161
|
-
return Data_Wrap_Struct(klass, cX25519_Scalar_mark, cX25519_Scalar_free, scalar);
|
162
|
-
}
|
163
|
-
|
164
|
-
static void cX25519_Scalar_mark(X25519_KEY *scalar)
|
165
|
-
{
|
166
|
-
}
|
167
|
-
|
168
|
-
static void cX25519_Scalar_free(X25519_KEY *scalar)
|
169
|
-
{
|
170
|
-
free(scalar);
|
171
|
-
}
|
172
|
-
|
173
|
-
/* Generate a random X25519 private scalar */
|
174
|
-
static VALUE cX25519_Scalar_generate(VALUE self)
|
175
|
-
{
|
176
|
-
VALUE rb_mSecureRandom, scalar_bytes;
|
177
|
-
rb_mSecureRandom = rb_const_get(rb_cObject, rb_intern("SecureRandom"));
|
178
|
-
|
179
|
-
scalar_bytes = rb_funcall(
|
180
|
-
rb_mSecureRandom,
|
181
|
-
rb_intern("random_bytes"),
|
182
|
-
1,
|
183
|
-
INT2NUM(X25519_KEYSIZE_BYTES)
|
184
|
-
);
|
185
|
-
|
186
|
-
return rb_class_new_instance(1, &scalar_bytes, self);
|
187
|
-
}
|
188
|
-
|
189
|
-
/* Create an X25519::Scalar from a String containing bytes */
|
190
|
-
static VALUE cX25519_Scalar_initialize(VALUE self, VALUE bytes)
|
191
|
-
{
|
192
|
-
X25519_KEY *scalar = NULL;
|
193
|
-
Data_Get_Struct(self, X25519_KEY, scalar);
|
194
|
-
|
195
|
-
StringValue(bytes);
|
196
|
-
if(RSTRING_LEN(bytes) != X25519_KEYSIZE_BYTES) {
|
197
|
-
rb_raise(
|
198
|
-
rb_eArgError,
|
199
|
-
"expected %d-byte scalar, got %ld",
|
200
|
-
X25519_KEYSIZE_BYTES,
|
201
|
-
RSTRING_LEN(bytes)
|
202
|
-
);
|
203
|
-
}
|
204
|
-
|
205
|
-
memcpy(scalar, RSTRING_PTR(bytes), X25519_KEYSIZE_BYTES);
|
206
|
-
|
207
|
-
return self;
|
208
|
-
}
|
209
|
-
|
210
|
-
/* Obtain a public key for an X25519 private scalar
|
211
|
-
* (i.e. fixed base scalar multiplication ) */
|
212
|
-
static VALUE cX25519_Scalar_multiply_base(VALUE self)
|
213
|
-
{
|
214
|
-
X25519_KEY *scalar = NULL, public_key;
|
215
|
-
VALUE public_key_str;
|
216
|
-
|
217
|
-
Data_Get_Struct(self, X25519_KEY, scalar);
|
218
|
-
|
219
|
-
/* Avoid using unitialized memory */
|
220
|
-
memset(&public_key, 0, X25519_KEYSIZE_BYTES);
|
221
|
-
|
222
|
-
/* Compute public key from private scalar using fixed-base scalar multiplication */
|
223
|
-
if(use_rfc7748_precomputed) {
|
224
|
-
x25519_rfc7748_precomputed_scalarmult_base(public_key, *scalar);
|
225
|
-
} else {
|
226
|
-
x25519_ref10_scalarmult_base(public_key, *scalar);
|
227
|
-
}
|
228
|
-
|
229
|
-
public_key_str = rb_str_new((const char *)&public_key, X25519_KEYSIZE_BYTES);
|
230
|
-
return rb_class_new_instance(1, &public_key_str, cX25519_MontgomeryU);
|
231
|
-
}
|
232
|
-
|
233
|
-
/* Obtain a public key for an X25519 private scalar
|
234
|
-
* (i.e. fixed base scalar multiplication ) */
|
235
|
-
static VALUE cX25519_Scalar_multiply(VALUE self, VALUE montgomery_u)
|
236
|
-
{
|
237
|
-
X25519_KEY *scalar = NULL, *coord = NULL, product;
|
238
|
-
VALUE product_str;
|
239
|
-
|
240
|
-
if(rb_obj_class(montgomery_u) != cX25519_MontgomeryU) {
|
241
|
-
rb_raise(rb_eTypeError, "wrong argument type (expected X25519::MontgomeryU)");
|
242
|
-
}
|
243
|
-
|
244
|
-
Data_Get_Struct(self, X25519_KEY, scalar);
|
245
|
-
Data_Get_Struct(montgomery_u, X25519_KEY, coord);
|
246
|
-
|
247
|
-
/* Avoid using unitialized memory */
|
248
|
-
memset(&product, 0, X25519_KEYSIZE_BYTES);
|
249
|
-
|
250
|
-
/* Compute the Diffie-Hellman shared secret */
|
251
|
-
if(use_rfc7748_precomputed) {
|
252
|
-
x25519_rfc7748_precomputed_scalarmult(product, *scalar, *coord);
|
253
|
-
} else {
|
254
|
-
x25519_ref10_scalarmult(product, *scalar, *coord);
|
255
|
-
}
|
256
|
-
|
257
|
-
product_str = rb_str_new((const char *)&product, X25519_KEYSIZE_BYTES);
|
258
|
-
return rb_class_new_instance(1, &product_str, cX25519_MontgomeryU);
|
259
|
-
}
|
260
|
-
|
261
|
-
/* Return a String containing the raw bytes of this scalar */
|
262
|
-
static VALUE cX25519_Scalar_to_bytes(VALUE self)
|
263
|
-
{
|
264
|
-
X25519_KEY *scalar = NULL;
|
265
|
-
Data_Get_Struct(self, X25519_KEY, scalar);
|
266
|
-
|
267
|
-
return rb_str_new((const char *)scalar, X25519_KEYSIZE_BYTES);;
|
268
|
-
}
|
269
|
-
|
270
|
-
/************************************
|
271
|
-
* X25519::MontgomeryU: public keys *
|
272
|
-
************************************/
|
273
|
-
|
274
|
-
static VALUE cX25519_MontgomeryU_allocate(VALUE klass)
|
275
|
-
{
|
276
|
-
X25519_KEY *coord = NULL;
|
277
|
-
|
278
|
-
/* Ensure allocation with the correct (32-byte) memory alignent */
|
279
|
-
if(posix_memalign((void **)&coord, ALIGN_BYTES, X25519_KEYSIZE_BYTES)) {
|
280
|
-
rb_fatal("x25519: can't allocate memory with posix_memalign()");
|
281
|
-
}
|
282
|
-
|
283
|
-
/* Avoid using unitialized memory */
|
284
|
-
memset(coord, 0, X25519_KEYSIZE_BYTES);
|
285
|
-
|
286
|
-
return Data_Wrap_Struct(klass, cX25519_MontgomeryU_mark, cX25519_MontgomeryU_free, coord);
|
287
|
-
}
|
288
|
-
|
289
|
-
static void cX25519_MontgomeryU_mark(X25519_KEY *coord)
|
290
|
-
{
|
291
|
-
}
|
292
|
-
|
293
|
-
static void cX25519_MontgomeryU_free(X25519_KEY *coord)
|
294
|
-
{
|
295
|
-
free(coord);
|
296
|
-
}
|
297
|
-
|
298
|
-
static VALUE cX25519_MontgomeryU_initialize(VALUE self, VALUE bytes)
|
299
|
-
{
|
300
|
-
X25519_KEY *coord = NULL;
|
301
|
-
Data_Get_Struct(self, X25519_KEY, coord);
|
302
|
-
|
303
|
-
StringValue(bytes);
|
304
|
-
if(RSTRING_LEN(bytes) != X25519_KEYSIZE_BYTES) {
|
305
|
-
rb_raise(
|
306
|
-
rb_eArgError,
|
307
|
-
"expected %d-byte scalar, got %ld",
|
308
|
-
X25519_KEYSIZE_BYTES,
|
309
|
-
RSTRING_LEN(bytes)
|
310
|
-
);
|
311
|
-
}
|
312
|
-
|
313
|
-
memcpy(coord, RSTRING_PTR(bytes), X25519_KEYSIZE_BYTES);
|
314
|
-
|
315
|
-
return self;
|
316
|
-
}
|
317
|
-
|
318
|
-
/* Return a String containing the raw bytes of this scalar */
|
319
|
-
static VALUE cX25519_MontgomeryU_to_bytes(VALUE self)
|
320
|
-
{
|
321
|
-
X25519_KEY *coord = NULL;
|
322
|
-
Data_Get_Struct(self, X25519_KEY, coord);
|
323
|
-
|
324
|
-
return rb_str_new((const char *)coord, X25519_KEYSIZE_BYTES);;
|
325
|
-
}
|
data/ext/x25519/x25519.h
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#include "rfc7748_precomputed.h"
|
2
|
-
|
3
|
-
/* Detect support for 4th gen (e.g. Haswell) or newer CPUs */
|
4
|
-
int check_4th_gen_intel_core_features();
|
5
|
-
|
6
|
-
/**********************************
|
7
|
-
* rfc7748_precomputed prototypes *
|
8
|
-
**********************************/
|
9
|
-
|
10
|
-
/* Fixed-base scalar multiplication */
|
11
|
-
void x25519_rfc7748_precomputed_scalarmult_base(uint8_t *session_key, uint8_t *private_key);
|
12
|
-
|
13
|
-
/* Variable-base scalar multiplication */
|
14
|
-
void x25519_rfc7748_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key, uint8_t *session_key);
|
15
|
-
|
16
|
-
/********************
|
17
|
-
* ref10 prototypes *
|
18
|
-
********************/
|
19
|
-
|
20
|
-
/* Fixed-base scalar multiplication */
|
21
|
-
int x25519_ref10_scalarmult_base(uint8_t *q, const uint8_t *n);
|
22
|
-
|
23
|
-
/* Variable-base scalar multiplication */
|
24
|
-
int x25519_ref10_scalarmult(uint8_t *q, const uint8_t *n, const uint8_t *p);
|