- Introduced `ibc_example.rs` demonstrating Inter-Blockchain Communication operations including cross-chain transfers, channel management, packet handling, and relayer operations. - Introduced `zk_example.rs` showcasing Zero-Knowledge proof operations such as circuit compilation, proof generation and verification, and on-chain verification with multiple proving systems.
344 lines
9.7 KiB
Go
344 lines
9.7 KiB
Go
// Package main demonstrates the Synor Crypto SDK for Go
|
|
//
|
|
// This example covers quantum-resistant cryptographic operations:
|
|
// - Hybrid Ed25519 + Dilithium3 signatures
|
|
// - BIP-39 mnemonic generation and validation
|
|
// - Post-quantum algorithms (Falcon, SPHINCS+)
|
|
// - Key derivation functions
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/synor/sdk-go/crypto"
|
|
)
|
|
|
|
func main() {
|
|
// Initialize client
|
|
config := crypto.Config{
|
|
APIKey: getEnv("SYNOR_API_KEY", "your-api-key"),
|
|
Endpoint: "https://crypto.synor.io/v1",
|
|
Timeout: 30 * time.Second,
|
|
Retries: 3,
|
|
Debug: false,
|
|
DefaultNetwork: crypto.NetworkMainnet,
|
|
}
|
|
|
|
client, err := crypto.NewClient(config)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create client: %v", err)
|
|
}
|
|
defer client.Close()
|
|
|
|
ctx := context.Background()
|
|
|
|
// Check service health
|
|
healthy, err := client.HealthCheck(ctx)
|
|
if err != nil {
|
|
log.Printf("Health check failed: %v", err)
|
|
} else {
|
|
fmt.Printf("Service healthy: %v\n\n", healthy)
|
|
}
|
|
|
|
// Run examples
|
|
mnemonicExample(ctx, client)
|
|
keypairExample(ctx, client)
|
|
signingExample(ctx, client)
|
|
falconExample(ctx, client)
|
|
sphincsExample(ctx, client)
|
|
kdfExample(ctx, client)
|
|
hashExample(ctx, client)
|
|
}
|
|
|
|
func mnemonicExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Mnemonic Operations ===")
|
|
|
|
// Generate a 24-word mnemonic (256-bit entropy)
|
|
mnemonic, err := client.Mnemonic.Generate(ctx, 24)
|
|
if err != nil {
|
|
log.Printf("Failed to generate mnemonic: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Generated mnemonic: %s\n", mnemonic.Phrase)
|
|
fmt.Printf("Word count: %d\n", mnemonic.WordCount)
|
|
|
|
// Validate a mnemonic
|
|
validation, err := client.Mnemonic.Validate(ctx, mnemonic.Phrase)
|
|
if err != nil {
|
|
log.Printf("Failed to validate mnemonic: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Valid: %v\n", validation.Valid)
|
|
if !validation.Valid {
|
|
fmt.Printf("Error: %s\n", validation.Error)
|
|
}
|
|
|
|
// Convert mnemonic to seed
|
|
seed, err := client.Mnemonic.ToSeed(ctx, mnemonic.Phrase, "optional-passphrase")
|
|
if err != nil {
|
|
log.Printf("Failed to convert to seed: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Seed (hex): %s...\n", fmt.Sprintf("%x", seed)[:32])
|
|
|
|
// Word suggestions for autocomplete
|
|
suggestions, err := client.Mnemonic.SuggestWords(ctx, "aban", 5)
|
|
if err != nil {
|
|
log.Printf("Failed to get suggestions: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Suggestions for 'aban': %v\n", suggestions)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func keypairExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Keypair Operations ===")
|
|
|
|
// Generate a random keypair
|
|
keypair, err := client.Keypairs.Generate(ctx)
|
|
if err != nil {
|
|
log.Printf("Failed to generate keypair: %v", err)
|
|
return
|
|
}
|
|
fmt.Println("Generated hybrid keypair:")
|
|
fmt.Printf(" Ed25519 public key size: %d bytes\n", len(keypair.PublicKey.Ed25519Bytes))
|
|
fmt.Printf(" Dilithium public key size: %d bytes\n", len(keypair.PublicKey.DilithiumBytes))
|
|
fmt.Printf(" Total public key size: %d bytes\n", keypair.PublicKey.Size)
|
|
|
|
// Get addresses for different networks
|
|
fmt.Println("\nAddresses:")
|
|
fmt.Printf(" Mainnet: %s\n", keypair.GetAddress(crypto.NetworkMainnet))
|
|
fmt.Printf(" Testnet: %s\n", keypair.GetAddress(crypto.NetworkTestnet))
|
|
fmt.Printf(" Devnet: %s\n", keypair.GetAddress(crypto.NetworkDevnet))
|
|
|
|
// Create keypair from mnemonic (deterministic)
|
|
mnemonic, err := client.Mnemonic.Generate(ctx, 24)
|
|
if err != nil {
|
|
log.Printf("Failed to generate mnemonic: %v", err)
|
|
return
|
|
}
|
|
|
|
keypair2, err := client.Keypairs.FromMnemonic(ctx, mnemonic.Phrase, "")
|
|
if err != nil {
|
|
log.Printf("Failed to create keypair from mnemonic: %v", err)
|
|
return
|
|
}
|
|
addr := keypair2.GetAddress(crypto.NetworkMainnet)
|
|
fmt.Printf("\nKeypair from mnemonic: %s...\n", addr[:20])
|
|
|
|
// Derive child keypair using BIP-44 path
|
|
path := crypto.DerivationPathExternal(0, 0) // m/44'/21337'/0'/0/0
|
|
fmt.Printf("Derivation path: %s\n", path)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func signingExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Hybrid Signing ===")
|
|
|
|
// Generate keypair
|
|
keypair, err := client.Keypairs.Generate(ctx)
|
|
if err != nil {
|
|
log.Printf("Failed to generate keypair: %v", err)
|
|
return
|
|
}
|
|
|
|
// Sign a message
|
|
message := []byte("Hello, quantum-resistant world!")
|
|
signature, err := client.Signing.Sign(ctx, keypair, message)
|
|
if err != nil {
|
|
log.Printf("Failed to sign message: %v", err)
|
|
return
|
|
}
|
|
|
|
fmt.Println("Signature created:")
|
|
fmt.Printf(" Ed25519 component: %d bytes\n", len(signature.Ed25519Bytes))
|
|
fmt.Printf(" Dilithium component: %d bytes\n", len(signature.DilithiumBytes))
|
|
fmt.Printf(" Total signature size: %d bytes\n", signature.Size)
|
|
|
|
// Verify the signature
|
|
valid, err := client.Signing.Verify(ctx, keypair.PublicKey, message, signature)
|
|
if err != nil {
|
|
log.Printf("Failed to verify signature: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("\nVerification result: %v\n", valid)
|
|
|
|
// Verify with tampered message fails
|
|
tamperedMessage := []byte("Hello, tampered message!")
|
|
invalidResult, err := client.Signing.Verify(ctx, keypair.PublicKey, tamperedMessage, signature)
|
|
if err != nil {
|
|
log.Printf("Failed to verify tampered signature: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Tampered message verification: %v\n", invalidResult)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func falconExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Falcon Post-Quantum Signatures ===")
|
|
|
|
// Generate Falcon-512 keypair (128-bit security)
|
|
falcon512, err := client.Falcon.Generate(ctx, crypto.Falcon512)
|
|
if err != nil {
|
|
log.Printf("Failed to generate Falcon-512 keypair: %v", err)
|
|
return
|
|
}
|
|
fmt.Println("Falcon-512 keypair:")
|
|
fmt.Printf(" Public key: %d bytes\n", len(falcon512.PublicKey.KeyBytes))
|
|
fmt.Println(" Security level: 128-bit")
|
|
|
|
// Generate Falcon-1024 keypair (256-bit security)
|
|
falcon1024, err := client.Falcon.Generate(ctx, crypto.Falcon1024)
|
|
if err != nil {
|
|
log.Printf("Failed to generate Falcon-1024 keypair: %v", err)
|
|
return
|
|
}
|
|
fmt.Println("\nFalcon-1024 keypair:")
|
|
fmt.Printf(" Public key: %d bytes\n", len(falcon1024.PublicKey.KeyBytes))
|
|
fmt.Println(" Security level: 256-bit")
|
|
|
|
// Sign with Falcon-512
|
|
message := []byte("Post-quantum secure message")
|
|
signature, err := client.Falcon.Sign(ctx, falcon512, message)
|
|
if err != nil {
|
|
log.Printf("Failed to sign with Falcon-512: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("\nFalcon-512 signature: %d bytes\n", len(signature.SignatureBytes))
|
|
|
|
// Verify
|
|
valid, err := client.Falcon.Verify(ctx, falcon512.PublicKey.KeyBytes, message, signature)
|
|
if err != nil {
|
|
log.Printf("Failed to verify Falcon signature: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Verification: %v\n", valid)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func sphincsExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== SPHINCS+ Hash-Based Signatures ===")
|
|
|
|
// SPHINCS+ variants with different security levels
|
|
variants := []struct {
|
|
variant crypto.SphincsVariant
|
|
security int
|
|
sigSize int
|
|
}{
|
|
{crypto.Shake128s, 128, 7856},
|
|
{crypto.Shake192s, 192, 16224},
|
|
{crypto.Shake256s, 256, 29792},
|
|
}
|
|
|
|
// Generate and demonstrate each variant
|
|
for _, v := range variants {
|
|
keypair, err := client.Sphincs.Generate(ctx, v.variant)
|
|
if err != nil {
|
|
log.Printf("Failed to generate SPHINCS+ keypair: %v", err)
|
|
continue
|
|
}
|
|
fmt.Printf("SPHINCS+ %s:\n", v.variant)
|
|
fmt.Printf(" Security level: %d-bit\n", v.security)
|
|
fmt.Printf(" Expected signature size: %d bytes\n", v.sigSize)
|
|
|
|
// Sign a message
|
|
message := []byte("Hash-based quantum security")
|
|
signature, err := client.Sphincs.Sign(ctx, keypair, message)
|
|
if err != nil {
|
|
log.Printf("Failed to sign with SPHINCS+: %v", err)
|
|
continue
|
|
}
|
|
fmt.Printf(" Actual signature size: %d bytes\n", len(signature.SignatureBytes))
|
|
|
|
// Verify
|
|
valid, err := client.Sphincs.Verify(ctx, keypair.PublicKey.KeyBytes, message, signature)
|
|
if err != nil {
|
|
log.Printf("Failed to verify SPHINCS+ signature: %v", err)
|
|
continue
|
|
}
|
|
fmt.Printf(" Verification: %v\n\n", valid)
|
|
}
|
|
}
|
|
|
|
func kdfExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Key Derivation Functions ===")
|
|
|
|
// HKDF (HMAC-based Key Derivation Function)
|
|
seed := []byte("master-secret-key-material-here")
|
|
hkdfConfig := crypto.DerivationConfig{
|
|
Salt: []byte("application-salt"),
|
|
Info: []byte("encryption-key"),
|
|
OutputLength: 32,
|
|
}
|
|
|
|
derivedKey, err := client.KDF.DeriveKey(ctx, seed, hkdfConfig)
|
|
if err != nil {
|
|
log.Printf("Failed to derive key with HKDF: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("HKDF derived key: %x\n", derivedKey)
|
|
|
|
// PBKDF2 (Password-Based Key Derivation Function)
|
|
password := []byte("user-password")
|
|
pbkdf2Config := crypto.PasswordDerivationConfig{
|
|
Salt: []byte("random-salt-value"),
|
|
Iterations: 100000,
|
|
OutputLength: 32,
|
|
}
|
|
|
|
passwordKey, err := client.KDF.DeriveFromPassword(ctx, password, pbkdf2Config)
|
|
if err != nil {
|
|
log.Printf("Failed to derive key with PBKDF2: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("PBKDF2 derived key: %x\n", passwordKey)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func hashExample(ctx context.Context, client *crypto.Client) {
|
|
fmt.Println("=== Hash Functions ===")
|
|
|
|
data := []byte("Data to hash")
|
|
|
|
// SHA3-256 (FIPS 202)
|
|
sha3, err := client.Hash.SHA3_256(ctx, data)
|
|
if err != nil {
|
|
log.Printf("Failed to compute SHA3-256: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("SHA3-256: %s\n", sha3.Hex)
|
|
|
|
// BLAKE3 (fast, parallel)
|
|
blake3, err := client.Hash.Blake3(ctx, data)
|
|
if err != nil {
|
|
log.Printf("Failed to compute BLAKE3: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("BLAKE3: %s\n", blake3.Hex)
|
|
|
|
// Keccak-256 (Ethereum compatible)
|
|
keccak, err := client.Hash.Keccak256(ctx, data)
|
|
if err != nil {
|
|
log.Printf("Failed to compute Keccak-256: %v", err)
|
|
return
|
|
}
|
|
fmt.Printf("Keccak: %s\n", keccak.Hex)
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|