Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ed25519 to curve25519 conversion helpers #217

Merged
merged 4 commits into from
Mar 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/rbnacl/signatures/ed25519/signing_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class SigningKey
:crypto_sign_ed25519_seed_keypair,
%i[pointer pointer pointer]

sodium_function :to_private_key,
:crypto_sign_ed25519_sk_to_curve25519,
%i[pointer pointer]

attr_reader :verify_key

# Generate a random SigningKey
Expand Down Expand Up @@ -123,6 +127,18 @@ def self.signature_bytes
def signature_bytes
Ed25519::SIGNATUREBYTES
end

# Return a new curve25519 (x25519) private key converted from this key
#
# it's recommeneded to read https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519
# as it encourages using distinct keys for signing and for encryption
#
# @return [RbNaCl::PrivateKey]
def to_curve25519_private_key
buffer = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PrivateKey::BYTES)
self.class.crypto_sign_ed25519_sk_to_curve25519(buffer, @signing_key)
Boxes::Curve25519XSalsa20Poly1305::PrivateKey.new(buffer)
end
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions lib/rbnacl/signatures/ed25519/verify_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class VerifyKey
:crypto_sign_ed25519_open,
%i[pointer pointer pointer ulong_long pointer]

sodium_function :to_public_key,
:crypto_sign_ed25519_pk_to_curve25519,
%i[pointer pointer]

# Create a new VerifyKey object from a public key.
#
# @param key [String] Ed25519 public key
Expand Down Expand Up @@ -99,6 +103,18 @@ def self.signature_bytes
def signature_bytes
Ed25519::SIGNATUREBYTES
end

# Return a new curve25519 (x25519) public key converted from this key
#
# it's recommeneded to read https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519
# as it encourages using distinct keys for signing and for encryption
#
# @return [RbNaCl::PublicKey]
def to_curve25519_public_key
buffer = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PublicKey::BYTES)
self.class.crypto_sign_ed25519_pk_to_curve25519(buffer, @key)
Boxes::Curve25519XSalsa20Poly1305::PublicKey.new(buffer)
end
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/rbnacl/test_vectors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ module RbNaCl
"376d7f3ac22ff372c18f613f2ae2e856af40",
sign_signature: "6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b" \
"4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509",
sign_curve25519_private: "38e5cdf33bc9e13086f58a3fea86d574e85e7865cffa5e8c9335f200a41d036c",
sign_curve25519_public: "35488a98f7ec26ae27099809afb27587b198b1197b5bcb0dec41153db2bf9952",

#
# SHA256 test vectors
Expand Down
7 changes: 7 additions & 0 deletions spec/rbnacl/signatures/ed25519/signing_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
let(:signing_keypair) { vector :sign_keypair }
let(:message) { vector :sign_message }
let(:signature) { vector :sign_signature }
let(:curve25519_private_key) { vector :sign_curve25519_private }

subject { described_class.new(signing_key) }

Expand All @@ -31,6 +32,12 @@
expect(subject.keypair_bytes).to eq signing_keypair
end

it "can be converted to curve25519 private key" do
sk = subject.to_curve25519_private_key
expect(sk).to be_a_kind_of RbNaCl::PrivateKey
expect(sk.to_s).to eq curve25519_private_key
end

include_examples "key equality" do
let(:key_bytes) { signing_key }
let(:key) { described_class.new(key_bytes) }
Expand Down
7 changes: 7 additions & 0 deletions spec/rbnacl/signatures/ed25519/verify_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

let(:message) { vector :sign_message }
let(:signature) { vector :sign_signature }
let(:curve25519_public_key) { vector :sign_curve25519_public }

let(:bad_signature) do
sig = signature.dup
Expand Down Expand Up @@ -52,6 +53,12 @@
expect(described_class.new(verify_key).to_s).to eq verify_key
end

it "can be converted to curve25519 public key" do
pk = subject.to_curve25519_public_key
expect(pk).to be_a_kind_of RbNaCl::PublicKey
expect(pk.to_s).to eq curve25519_public_key
end

include_examples "key equality" do
let(:key_bytes) { verify_key }
let(:key) { described_class.new(verify_key) }
Expand Down