module X25519
The X25519
elliptic curve Diffie-Hellman algorithm
Constants
- InvalidKeyError
Raised when we detect a degenerate (i.e. all-zero) public key
- KEY_SIZE
Size of an
X25519
key (public or private) in bytes- SelfTestFailure
Raised when the built-in self-test fails
- VERSION
Attributes
Obtain the backend provider module
Public Instance Methods
Raw fixed-base scalar multiplication function that acts directly on bytestrings. Calculates the coordinate of the elliptic curve point that represents the public key for a given scalar.
@param scalar_bytes [String] a serialized private scalar
@return [String] compressed Montgomery-u coordinate of the resulting point
# File lib/x25519.rb, line 48 def calculate_public_key(scalar_bytes) validate_key_bytes(scalar_bytes) provider.scalarmult_base(scalar_bytes) end
Raw Diffie-Hellman function that acts directly on bytestrings. An alternative to the object-oriented API
@param scalar_bytes [String] a serialized private scalar @param montgomery_u_bytes [String] a point we wish to multiply by the scalar
@return [String] resulting point, serialized as bytes
# File lib/x25519.rb, line 60 def diffie_hellman(scalar_bytes, montgomery_u_bytes) validate_key_bytes(scalar_bytes) validate_key_bytes(montgomery_u_bytes) # The point located at a Montgomery-u coordinate of zero always returns # the point at zero regardless of which scalar it's multiplied with raise InvalidKeyError, "degenerate public key" if montgomery_u_bytes == ("\0" * KEY_SIZE) provider.scalarmult(scalar_bytes, montgomery_u_bytes) end
Perform a self-test to ensure the selected provider is working
# File lib/x25519.rb, line 80 def self_test X25519::TestVectors::VARIABLE_BASE.each do |v| shared_secret = provider.scalarmult([v.scalar].pack("H*"), [v.input_coord].pack("H*")) raise SelfTestFailure, "self test failed!" unless shared_secret.unpack1("H*") == v.output_coord end X25519::TestVectors::FIXED_BASE.each do |v| public_key = provider.scalarmult_base([v.scalar].pack("H*")) raise SelfTestFailure, "self test failed!" unless public_key.unpack1("H*") == v.output_coord end true end
Ensure a serialized key meets the requirements
# File lib/x25519.rb, line 72 def validate_key_bytes(key_bytes) raise TypeError, "expected String, got #{key_bytes.class}" unless key_bytes.is_a?(String) return true if key_bytes.bytesize == KEY_SIZE raise ArgumentError, "expected #{KEY_SIZE}-byte String, got #{key_bytes.bytesize}" end