diff --git a/spec/sodium/sign/secret_key_spec.cr b/spec/sodium/sign/secret_key_spec.cr index 3599325..20db91a 100644 --- a/spec/sodium/sign/secret_key_spec.cr +++ b/spec/sodium/sign/secret_key_spec.cr @@ -1,5 +1,6 @@ require "../../spec_helper" require "../../../src/sodium/sign/secret_key" +require "../../../src/sodium/crypto_box/secret_key" detached_test_vectors = [ { @@ -71,6 +72,12 @@ describe Sodium::Sign::SecretKey do end end + it "to_curve25519" do + message = "foo" + sskey = Sodium::Sign::SecretKey.new + cskey = sskey.to_curve25519 + end + it "RbNaCl detached test vectors" do detached_test_vectors.each do |vec| seckey, plaintext, signature = sign_from_vec vec diff --git a/src/sodium/crypto_box/secret_key.cr b/src/sodium/crypto_box/secret_key.cr index c019ab5..e7f633c 100644 --- a/src/sodium/crypto_box/secret_key.cr +++ b/src/sodium/crypto_box/secret_key.cr @@ -55,6 +55,22 @@ class Sodium::CryptoBox end end + # Use existing secret and public keys. + # + # Takes ownership of an existing key in a SecureBuffer. + # Recomputes the public key from a secret key if missing. + def initialize(@sbuf : SecureBuffer, pkey : Bytes? = nil) + raise ArgumentError.new("Secret key must be #{KEY_SIZE} bytes, got #{@sbuf.bytesize}") if @sbuf.bytesize != KEY_SIZE + if pk = pkey + @public_key = PublicKey.new pk + else + @public_key = PublicKey.new + if LibSodium.crypto_scalarmult_base(@public_key.to_slice, self.to_slice) != 0 + raise Sodium::Error.new("crypto_scalarmult_base") + end + end + end + # Use existing secret and public keys. # # Copies secret key to a SecureBuffer. diff --git a/src/sodium/lib_sodium.cr b/src/sodium/lib_sodium.cr index e846cea..62952a0 100644 --- a/src/sodium/lib_sodium.cr +++ b/src/sodium/lib_sodium.cr @@ -379,7 +379,7 @@ module Sodium fun crypto_sign_ed25519_seed_keypair(pk : UInt8*, sk : UInt8*, seed : UInt8*) : LibC::Int fun crypto_sign_ed25519_seedbytes : LibC::SizeT fun crypto_sign_ed25519_sk_to_curve25519(curve25519_sk : UInt8*, ed25519_sk : UInt8*) : LibC::Int - # fun crypto_sign_ed25519_sk_to_pk(pk : UInt8*, sk : UInt8*) : LibC::Int + # fun crypto_sign_ed25519_sk_to_pk(pk : UInt8*, sk : UInt8*) : LibC::Int fun crypto_sign_ed25519_sk_to_seed(seed : UInt8*, sk : UInt8*) : LibC::Int fun crypto_sign_ed25519_verify_detached(sig : UInt8*, m : UInt8*, mlen : LibC::ULongLong, pk : UInt8*) : LibC::Int fun crypto_sign_ed25519ph_final_create(state : CryptoSignEd25519phState*, sig : UInt8*, siglen_p : LibC::ULongLong*, sk : UInt8*) : LibC::Int diff --git a/src/sodium/sign/secret_key.cr b/src/sodium/sign/secret_key.cr index 86bb807..9e158de 100644 --- a/src/sodium/sign/secret_key.cr +++ b/src/sodium/sign/secret_key.cr @@ -83,5 +83,12 @@ module Sodium end sig end + + def to_curve25519 : CryptoBox::SecretKey + key = SecureBuffer.new CryptoBox::SecretKey::KEY_SIZE + LibSodium.crypto_sign_ed25519_sk_to_curve25519 key.to_slice, @sbuf.to_slice + key.readonly + CryptoBox::SecretKey.new key + end end end