Module: NwcRuby::Crypto::Keys
- Defined in:
- lib/nwc_ruby/crypto/keys.rb
Overview
Key helpers: hex <-> bytes, private key -> x-only pubkey, validation.
Nostr uses BIP-340 Schnorr signatures over secp256k1. Public keys are “x-only” — just the 32-byte X coordinate. We use rbsecp256k1 (which wraps libsecp256k1) to derive them correctly.
Class Method Summary collapse
- .bytes_to_hex(bytes) ⇒ Object
-
.generate_private_key ⇒ Object
Generate a new 32-byte private key as a lowercase hex string.
- .hex_to_bytes(hex) ⇒ Object
-
.public_key_from_private(privkey_hex) ⇒ Object
Derive the 32-byte x-only public key (hex) from a private key (hex).
- .validate_hex32!(hex, label = 'value') ⇒ Object
Class Method Details
.bytes_to_hex(bytes) ⇒ Object
35 36 37 |
# File 'lib/nwc_ruby/crypto/keys.rb', line 35 def bytes_to_hex(bytes) bytes.unpack1('H*') end |
.generate_private_key ⇒ Object
Generate a new 32-byte private key as a lowercase hex string.
16 17 18 |
# File 'lib/nwc_ruby/crypto/keys.rb', line 16 def generate_private_key SecureRandom.bytes(32).unpack1('H*') end |
.hex_to_bytes(hex) ⇒ Object
31 32 33 |
# File 'lib/nwc_ruby/crypto/keys.rb', line 31 def hex_to_bytes(hex) [hex].pack('H*') end |
.public_key_from_private(privkey_hex) ⇒ Object
Derive the 32-byte x-only public key (hex) from a private key (hex).
21 22 23 24 25 26 27 28 29 |
# File 'lib/nwc_ruby/crypto/keys.rb', line 21 def public_key_from_private(privkey_hex) validate_hex32!(privkey_hex, 'private key') ctx = ::Secp256k1::Context.create kp = ctx.key_pair_from_private_key(hex_to_bytes(privkey_hex)) # rbsecp256k1 gives us a compressed public key (33 bytes, 02/03 prefix). # X-only pubkey is just bytes 1..32. compressed = kp.public_key.compressed bytes_to_hex(compressed[1, 32]) end |
.validate_hex32!(hex, label = 'value') ⇒ Object
39 40 41 42 43 |
# File 'lib/nwc_ruby/crypto/keys.rb', line 39 def validate_hex32!(hex, label = 'value') return if hex.is_a?(String) && hex.match?(/\A[0-9a-fA-F]{64}\z/) raise InvalidConnectionStringError, "#{label} must be 64 hex characters (32 bytes)" end |