Wilson Silva
Wilson Silva
All Posts Mar 19 2024

Nostr 0.6.0 - Signatures

I’m excited to share the release of version 0.6.0 of the nostr gem. Marking a significant update with a focus on enhancing cryptographic functionalities and introducing a systematic approach to documenting architectural decisions.

What’s new in 0.6.0?

  • Architecture Decision Records (ADRs)
  • Message signing and verification
  • Event signature verification
  • KeyPair destructuring

Detailed Overview

Architecture Decision Records (ADRs)

I’ve begun documenting architectural decisions using Architecture Decision Records (ADRs). This structured approach aids in recording architectural changes and their rationale.

An ADR typically includes the following sections:

  • Title: A short, descriptive name for the architectural decision.
  • Status: The current status (proposed, accepted, deprecated, etc.) of the decision.
  • Context: The circumstances that led to the decision being considered.
  • Decision: A detailed explanation of the decision.
  • Consequences: The expected impact of the decision, both positive and negative.

Here’s an abbreviated example of an ADR for introducing the Signature class:

# ADR 0001: Introduction of Signature Class

## Status

Accepted

## Context

Before the introduction of the `Signature` class, signatures were
handled as simple strings throughout the nostr gem, leading to
repeated validation logic and the potential for errors.

## Decision

To encapsulate signature handling and validation in a single,
cohesive unit, we introduced the `Signature` class. This class
enforces the necessary validations at the point of creation,
providing a more robust and error-resistant approach.

## Consequences

Positive:
- Centralized signature validation logic, reducing repetition and potential errors.
- Improved code readability and maintainability.

Negative:
- Requires updates to existing codebases to utilize the new class.
- Adds a slight learning curve for new developers.

Message signing and verification

Introducing a Signature class addresses primitive obsession with string signatures by providing a dedicated class for signature handling, including validation and error handling.

signature = Nostr::Signature.new('your_signature_here')

This may raise InvalidSignatureTypeError, InvalidSignatureLengthError, or InvalidSignatureFormatError if the signature is invalid.

Furthermore, new functionalities for signing messages and verifying the authenticity of messages and events have been added, ensuring data integrity within the nostr ecosystem.

key_pair = Nostr::KeyPair.new(
  private_key: Nostr::PrivateKey.new('7d1e4219a5e7d8342654c675085bfbdee143f0eb0f0921f5541ef1705a2b407d'),
  public_key: Nostr::PublicKey.new('15678d8fbc126fa326fac536acd5a6dcb5ef64b3d939abe31d6830cba6cd26d6'),
)

crypto = Nostr::Crypto.new
message = 'Hello, nostr!'
signature = crypto.sign_message(message, key_pair.private_key)
crypto.valid_sig?(message, key_pair.public_key, signature) # => true

The valid_sig? method checks if a signature is valid, whereas check_sig! raises an error if the signature is invalid.

Event signature verification

Signing an event ensures its authenticity. Verification confirms the event was not tampered with.

event.sign(private_key)
event.verify_signature # true or false

KeyPair destructuring

Enhancing usability, the KeyPair class now supports destructuring, making it easier to work with private and public keys.

key_pair = Nostr::KeyPair.new(
  private_key: Nostr::PrivateKey.new('7d1e4219a5e7d8342654c675085bfbdee143f0eb0f0921f5541ef1705a2b407d'),
  public_key: Nostr::PublicKey.new('15678d8fbc126fa326fac536acd5a6dcb5ef64b3d939abe31d6830cba6cd26d6'),
)
private_key, public_key = key_pair

Coming next

The next release will focus on enhancing error messages and debugging capabilities. Feedback is welcome as development continues. Feel free to start a discussion on the GitHub repository.