# frozen_string_literal: true module X25519 # X25519 private keys # # Scalars are the integer component of scalar multiplication, multiplied # against an elliptic curve point. class Scalar # Securely generate a random scalar def self.generate new(SecureRandom.random_bytes(X25519::KEY_SIZE)) end # Create an X25519 scalar object from a bytestring # # @param bytes [String] 32-byte random secret scalar def initialize(bytes) X25519.validate_key_bytes(bytes) @scalar_bytes = bytes end # Variable-base scalar multiplication a.k.a. Diffie-Hellman # # This can be used to obtain a shared secret from a public key # # @param montgomery_u [X25519::MontgomeryU] coordinate of the public key/point to perform D-H with # # @return [X25519::MontgomeryU] resulting point (i.e. D-H shared secret) def diffie_hellman(montgomery_u) raise TypeError, "expected X25519::MontgomeryU, got #{montgomery_u}" unless montgomery_u.is_a?(MontgomeryU) MontgomeryU.new(X25519.diffie_hellman(@scalar_bytes, montgomery_u.to_bytes)) end alias multiply diffie_hellman # Fixed-base scalar multiplication. Calculates a public key from a # private scalar # # @return [X25519::MontgomeryU] resulting point (i.e. public key) def public_key MontgomeryU.new(X25519.calculate_public_key(@scalar_bytes)) end alias multiply_base public_key # Return a bytestring representation of this scalar # # @return [String] scalar converted to a bytestring def to_bytes @scalar_bytes end # String inspection that does not leak the private scalar def inspect to_s end end end