Module: CZTop::CURVE

Defined in:
lib/cztop/curve.rb,
lib/cztop/curve/auth.rb

Overview

CURVE encryption utilities for ZeroMQ.

Provides keypair generation, key derivation, and Z85 encoding/decoding. CURVE options are applied to sockets via the curve: keyword argument in socket constructors — there are no public CURVE methods on Socket.

Defined Under Namespace

Classes: Auth

Constant Summary collapse

KEY_SIZE =
32

Class Method Summary collapse

Class Method Details

.available?Boolean

Whether CURVE encryption is available in the linked libzmq.

Returns:

  • (Boolean)


18
19
20
# File 'lib/cztop/curve.rb', line 18

def self.available?
  CZMQ::FFI.zsys_has_curve
end

.keypairArray(String, String)

Generates a new CURVE keypair.

Returns:

  • (Array(String, String))

    [public_key, secret_key] as 32-byte binary strings

Raises:

  • (NotImplementedError)

    if CURVE is not available



26
27
28
29
30
31
32
33
# File 'lib/cztop/curve.rb', line 26

def self.keypair
  _require_curve!
  pub_buf = ::FFI::MemoryPointer.new(:char, 41)  # Z85 is 40 chars + null
  sec_buf = ::FFI::MemoryPointer.new(:char, 41)
  rc = CZMQ::FFI.zmq_curve_keypair(pub_buf, sec_buf)
  raise 'zmq_curve_keypair failed' unless rc == 0
  [z85_decode(pub_buf.read_string), z85_decode(sec_buf.read_string)]
end

.public_key(secret_key) ⇒ String

Derives the public key from a secret key.

Parameters:

  • secret_key (String)

    32-byte binary secret key

Returns:

  • (String)

    32-byte binary public key

Raises:

  • (ArgumentError)

    if secret_key is not 32 bytes

  • (NotImplementedError)

    if CURVE is not available



41
42
43
44
45
46
47
48
49
# File 'lib/cztop/curve.rb', line 41

def self.public_key(secret_key)
  _require_curve!
  _check_key!(secret_key, 'secret_key')
  sec_z85 = z85_encode(secret_key)
  pub_buf = ::FFI::MemoryPointer.new(:char, 41)
  rc = CZMQ::FFI.zmq_curve_public(pub_buf, sec_z85)
  raise 'zmq_curve_public failed' unless rc == 0
  z85_decode(pub_buf.read_string)
end

.setup_client!(socket, secret_key, server_pubkey) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Configures a socket as a CURVE client.



96
97
98
99
100
101
102
103
104
105
# File 'lib/cztop/curve.rb', line 96

def self.setup_client!(socket, secret_key, server_pubkey)
  _require_curve!
  _check_key!(secret_key, 'secret_key')
  _check_key!(server_pubkey, 'server_key')
  pubkey = public_key(secret_key)
  ptr = socket.to_ptr
  _set_key(ptr, :zsock_set_curve_publickey_bin, pubkey)
  _set_key(ptr, :zsock_set_curve_secretkey_bin, secret_key)
  _set_key(ptr, :zsock_set_curve_serverkey_bin, server_pubkey)
end

.setup_server!(socket, secret_key) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Configures a socket as a CURVE server.



82
83
84
85
86
87
88
89
90
91
# File 'lib/cztop/curve.rb', line 82

def self.setup_server!(socket, secret_key)
  _require_curve!
  _check_key!(secret_key, 'secret_key')
  pubkey = public_key(secret_key)
  ptr = socket.to_ptr
  CZMQ::FFI.zsock_set_curve_server(ptr, 1)
  _set_key(ptr, :zsock_set_curve_publickey_bin, pubkey)
  _set_key(ptr, :zsock_set_curve_secretkey_bin, secret_key)
  CZMQ::FFI.zsock_set_zap_domain(ptr, 'global')
end

.z85_decode(z85) ⇒ String

Decodes a Z85-encoded string to binary.

Parameters:

  • z85 (String)

    Z85-encoded string (length must be divisible by 5)

Returns:

  • (String)

    binary data

Raises:

  • (ArgumentError)

    if length is not divisible by 5



70
71
72
73
74
75
76
77
# File 'lib/cztop/curve.rb', line 70

def self.z85_decode(z85)
  raise ArgumentError, 'Z85 length must be divisible by 5' unless (z85.bytesize % 5).zero?
  bin_size = z85.bytesize * 4 / 5
  buf = ::FFI::MemoryPointer.new(:char, bin_size)
  result = CZMQ::FFI.zmq_z85_decode(buf, z85)
  raise 'zmq_z85_decode failed' if result.null?
  buf.read_string(bin_size).b
end

.z85_encode(binary) ⇒ String

Encodes a binary string to Z85.

Parameters:

  • binary (String)

    binary data (length must be divisible by 4)

Returns:

  • (String)

    Z85-encoded string

Raises:

  • (ArgumentError)

    if length is not divisible by 4



56
57
58
59
60
61
62
63
# File 'lib/cztop/curve.rb', line 56

def self.z85_encode(binary)
  binary = binary.b
  raise ArgumentError, 'binary length must be divisible by 4' unless (binary.bytesize % 4).zero?
  buf = ::FFI::MemoryPointer.new(:char, binary.bytesize * 5 / 4 + 1)
  result = CZMQ::FFI.zmq_z85_encode(buf, binary, binary.bytesize)
  raise 'zmq_z85_encode failed' if result.null?
  buf.read_string
end