Add example code demonstrating all SDK services (Crypto, DEX, ZK, IBC, Compiler) for the remaining languages: - C SDK (5 examples): Using synor_* C API with explicit memory management - C++ SDK (5 examples): Modern C++17 with RAII and designated initializers - C# SDK (5 examples): Async/await patterns with .NET conventions - Ruby SDK (5 examples): Ruby idioms with blocks and symbols Each example covers: - Crypto: Hybrid signatures, mnemonics, Falcon, SPHINCS+, KDF, hashing - DEX: Markets, spot trading, perpetuals, liquidity, portfolio - ZK: Circuits, Groth16, PLONK, STARK, recursive proofs, ceremonies - IBC: Chains, channels, transfers, packets, relayer, monitoring - Compiler: Compilation, optimization, ABI, analysis, validation, security
241 lines
7.2 KiB
Ruby
241 lines
7.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Synor Crypto SDK Examples for Ruby
|
|
#
|
|
# Demonstrates quantum-resistant cryptographic operations:
|
|
# - Hybrid Ed25519 + Dilithium3 signatures
|
|
# - BIP-39 mnemonic generation and validation
|
|
# - Post-quantum algorithms (Falcon, SPHINCS+)
|
|
# - Key derivation functions
|
|
#
|
|
|
|
require 'synor/crypto'
|
|
|
|
class CryptoExample
|
|
def initialize(crypto)
|
|
@crypto = crypto
|
|
end
|
|
|
|
def run_mnemonic_example
|
|
puts '=== Mnemonic Operations ==='
|
|
|
|
# Generate a 24-word mnemonic (256-bit entropy)
|
|
mnemonic = @crypto.mnemonic.generate(24)
|
|
puts "Generated mnemonic: #{mnemonic.phrase}"
|
|
puts "Word count: #{mnemonic.word_count}"
|
|
|
|
# Validate a mnemonic
|
|
validation = @crypto.mnemonic.validate(mnemonic.phrase)
|
|
puts "Valid: #{validation.valid?}"
|
|
puts "Error: #{validation.error}" unless validation.valid?
|
|
|
|
# Convert mnemonic to seed
|
|
seed = @crypto.mnemonic.to_seed(mnemonic.phrase, 'optional-passphrase')
|
|
puts "Seed (hex): #{bytes_to_hex(seed, 16)}..."
|
|
|
|
# Word suggestions for autocomplete
|
|
suggestions = @crypto.mnemonic.suggest_words('aban', 5)
|
|
puts "Suggestions for 'aban': #{suggestions.join(', ')}"
|
|
puts
|
|
end
|
|
|
|
def run_keypair_example
|
|
puts '=== Keypair Operations ==='
|
|
|
|
# Generate a random keypair
|
|
keypair = @crypto.keypairs.generate
|
|
puts 'Generated hybrid keypair:'
|
|
puts " Ed25519 public key size: #{keypair.public_key.ed25519_bytes.length} bytes"
|
|
puts " Dilithium public key size: #{keypair.public_key.dilithium_bytes.length} bytes"
|
|
puts " Total public key size: #{keypair.public_key.size} bytes"
|
|
|
|
# Get addresses for different networks
|
|
puts "\nAddresses:"
|
|
puts " Mainnet: #{keypair.get_address(:mainnet)}"
|
|
puts " Testnet: #{keypair.get_address(:testnet)}"
|
|
puts " Devnet: #{keypair.get_address(:devnet)}"
|
|
|
|
# Create keypair from mnemonic (deterministic)
|
|
mnemonic = @crypto.mnemonic.generate(24)
|
|
keypair2 = @crypto.keypairs.from_mnemonic(mnemonic.phrase)
|
|
addr = keypair2.get_address(:mainnet)
|
|
puts "\nKeypair from mnemonic: #{addr[0, 20]}..."
|
|
|
|
# Derive child keypair using BIP-44 path
|
|
path = Synor::Crypto::DerivationPath.external(0, 0) # m/44'/21337'/0'/0/0
|
|
puts "Derivation path: #{path}"
|
|
puts
|
|
end
|
|
|
|
def run_signing_example
|
|
puts '=== Hybrid Signing ==='
|
|
|
|
# Generate keypair
|
|
keypair = @crypto.keypairs.generate
|
|
|
|
# Sign a message
|
|
message = 'Hello, quantum-resistant world!'.bytes
|
|
signature = @crypto.signing.sign(keypair, message)
|
|
|
|
puts 'Signature created:'
|
|
puts " Ed25519 component: #{signature.ed25519_bytes.length} bytes"
|
|
puts " Dilithium component: #{signature.dilithium_bytes.length} bytes"
|
|
puts " Total signature size: #{signature.size} bytes"
|
|
|
|
# Verify the signature
|
|
valid = @crypto.signing.verify(keypair.public_key, message, signature)
|
|
puts "\nVerification result: #{valid}"
|
|
|
|
# Verify with tampered message fails
|
|
tampered_message = 'Hello, tampered message!'.bytes
|
|
invalid_result = @crypto.signing.verify(keypair.public_key, tampered_message, signature)
|
|
puts "Tampered message verification: #{invalid_result}"
|
|
puts
|
|
end
|
|
|
|
def run_falcon_example
|
|
puts '=== Falcon Post-Quantum Signatures ==='
|
|
|
|
# Generate Falcon-512 keypair (128-bit security)
|
|
falcon512 = @crypto.falcon.generate(:falcon512)
|
|
puts 'Falcon-512 keypair:'
|
|
puts " Public key: #{falcon512.public_key.key_bytes.length} bytes"
|
|
puts ' Security level: 128-bit'
|
|
|
|
# Generate Falcon-1024 keypair (256-bit security)
|
|
falcon1024 = @crypto.falcon.generate(:falcon1024)
|
|
puts "\nFalcon-1024 keypair:"
|
|
puts " Public key: #{falcon1024.public_key.key_bytes.length} bytes"
|
|
puts ' Security level: 256-bit'
|
|
|
|
# Sign with Falcon-512
|
|
message = 'Post-quantum secure message'.bytes
|
|
signature = @crypto.falcon.sign(falcon512, message)
|
|
puts "\nFalcon-512 signature: #{signature.signature_bytes.length} bytes"
|
|
|
|
# Verify
|
|
valid = @crypto.falcon.verify(falcon512.public_key.key_bytes, message, signature)
|
|
puts "Verification: #{valid}"
|
|
puts
|
|
end
|
|
|
|
def run_sphincs_example
|
|
puts '=== SPHINCS+ Hash-Based Signatures ==='
|
|
|
|
# SPHINCS+ variants with different security levels
|
|
variants = [
|
|
{ variant: :shake128s, security: 128, sig_size: 7856, name: 'SHAKE128S' },
|
|
{ variant: :shake192s, security: 192, sig_size: 16_224, name: 'SHAKE192S' },
|
|
{ variant: :shake256s, security: 256, sig_size: 29_792, name: 'SHAKE256S' }
|
|
]
|
|
|
|
message = 'Hash-based quantum security'.bytes
|
|
|
|
variants.each do |v|
|
|
keypair = @crypto.sphincs.generate(v[:variant])
|
|
puts "SPHINCS+ #{v[:name]}:"
|
|
puts " Security level: #{v[:security]}-bit"
|
|
puts " Expected signature size: #{v[:sig_size]} bytes"
|
|
|
|
# Sign a message
|
|
signature = @crypto.sphincs.sign(keypair, message)
|
|
puts " Actual signature size: #{signature.signature_bytes.length} bytes"
|
|
|
|
# Verify
|
|
valid = @crypto.sphincs.verify(keypair.public_key.key_bytes, message, signature)
|
|
puts " Verification: #{valid}"
|
|
puts
|
|
end
|
|
end
|
|
|
|
def run_kdf_example
|
|
puts '=== Key Derivation Functions ==='
|
|
|
|
# HKDF (HMAC-based Key Derivation Function)
|
|
seed = 'master-secret-key-material-here'.bytes
|
|
hkdf_config = {
|
|
salt: 'application-salt'.bytes,
|
|
info: 'encryption-key'.bytes,
|
|
output_length: 32
|
|
}
|
|
|
|
derived_key = @crypto.kdf.derive_key(seed, hkdf_config)
|
|
puts "HKDF derived key: #{bytes_to_hex(derived_key)}"
|
|
|
|
# PBKDF2 (Password-Based Key Derivation Function)
|
|
password = 'user-password'.bytes
|
|
pbkdf2_config = {
|
|
salt: 'random-salt-value'.bytes,
|
|
iterations: 100_000,
|
|
output_length: 32
|
|
}
|
|
|
|
password_key = @crypto.kdf.derive_from_password(password, pbkdf2_config)
|
|
puts "PBKDF2 derived key: #{bytes_to_hex(password_key)}"
|
|
puts
|
|
end
|
|
|
|
def run_hash_example
|
|
puts '=== Hash Functions ==='
|
|
|
|
data = 'Data to hash'.bytes
|
|
|
|
# SHA3-256 (FIPS 202)
|
|
sha3 = @crypto.hash.sha3_256(data)
|
|
puts "SHA3-256: #{sha3.hex}"
|
|
|
|
# BLAKE3 (fast, parallel)
|
|
blake3 = @crypto.hash.blake3(data)
|
|
puts "BLAKE3: #{blake3.hex}"
|
|
|
|
# Keccak-256 (Ethereum compatible)
|
|
keccak = @crypto.hash.keccak256(data)
|
|
puts "Keccak: #{keccak.hex}"
|
|
puts
|
|
end
|
|
|
|
private
|
|
|
|
def bytes_to_hex(data, max_len = nil)
|
|
len = max_len || data.length
|
|
hex = data[0, len].map { |b| format('%02x', b) }.join
|
|
hex += '...' if max_len && max_len < data.length
|
|
hex
|
|
end
|
|
end
|
|
|
|
# Main execution
|
|
if __FILE__ == $PROGRAM_NAME
|
|
# Initialize client
|
|
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
|
|
config = Synor::Crypto::Config.new(
|
|
api_key: api_key,
|
|
endpoint: 'https://crypto.synor.io/v1',
|
|
timeout: 30,
|
|
retries: 3,
|
|
debug: false,
|
|
default_network: :mainnet
|
|
)
|
|
|
|
crypto = Synor::Crypto::Client.new(config)
|
|
example = CryptoExample.new(crypto)
|
|
|
|
begin
|
|
# Check service health
|
|
healthy = crypto.health_check
|
|
puts "Service healthy: #{healthy}\n\n"
|
|
|
|
# Run examples
|
|
example.run_mnemonic_example
|
|
example.run_keypair_example
|
|
example.run_signing_example
|
|
example.run_falcon_example
|
|
example.run_sphincs_example
|
|
example.run_kdf_example
|
|
example.run_hash_example
|
|
rescue StandardError => e
|
|
warn "Error: #{e.message}"
|
|
exit 1
|
|
end
|
|
end
|