Refactor crypto package to use p256k1 signer
- Replaced the p256k package with p256k1.mleku.dev/signer across the codebase, updating all instances where the previous signer was utilized. - Removed the deprecated p256k package, including all related files and tests, to streamline the codebase and improve maintainability. - Updated various components, including event handling, database interactions, and protocol implementations, to ensure compatibility with the new signer interface. - Enhanced tests to validate the new signing functionality and ensure robustness across the application. - Bumped version to v0.23.3 to reflect these changes.
This commit is contained in:
18
.github/workflows/go.yml
vendored
18
.github/workflows/go.yml
vendored
@@ -29,15 +29,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: "1.25"
|
go-version: "1.25"
|
||||||
|
|
||||||
- name: Install libsecp256k1
|
|
||||||
run: ./scripts/ubuntu_install_libsecp256k1.sh
|
|
||||||
|
|
||||||
- name: Build with cgo
|
|
||||||
run: go build -v ./...
|
|
||||||
|
|
||||||
- name: Test with cgo
|
|
||||||
run: go test -v $(go list ./... | xargs -n1 sh -c 'ls $0/*_test.go 1>/dev/null 2>&1 && echo $0' | grep .)
|
|
||||||
|
|
||||||
- name: Set CGO off
|
- name: Set CGO off
|
||||||
run: echo "CGO_ENABLED=0" >> $GITHUB_ENV
|
run: echo "CGO_ENABLED=0" >> $GITHUB_ENV
|
||||||
|
|
||||||
@@ -61,9 +52,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '1.25'
|
go-version: '1.25'
|
||||||
|
|
||||||
- name: Install libsecp256k1
|
|
||||||
run: ./scripts/ubuntu_install_libsecp256k1.sh
|
|
||||||
|
|
||||||
- name: Build Release Binaries
|
- name: Build Release Binaries
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
run: |
|
run: |
|
||||||
@@ -75,11 +63,7 @@ jobs:
|
|||||||
mkdir -p release-binaries
|
mkdir -p release-binaries
|
||||||
|
|
||||||
# Build for different platforms
|
# Build for different platforms
|
||||||
GOEXPERIMENT=greenteagc,jsonv2 GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -ldflags "-s -w" -o release-binaries/orly-${VERSION}-linux-amd64 .
|
GOEXPERIMENT=greenteagc,jsonv2 GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w" -o release-binaries/orly-${VERSION}-linux-amd64 .
|
||||||
# GOEXPERIMENT=greenteagc,jsonv2 GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o release-binaries/orly-${VERSION}-linux-arm64 .
|
|
||||||
# GOEXPERIMENT=greenteagc,jsonv2 GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -o release-binaries/orly-${VERSION}-darwin-amd64 .
|
|
||||||
# GOEXPERIMENT=greenteagc,jsonv2 GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -o release-binaries/orly-${VERSION}-darwin-arm64 .
|
|
||||||
# GOEXPERIMENT=greenteagc,jsonv2 GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o release-binaries/orly-${VERSION}-windows-amd64.exe .
|
|
||||||
|
|
||||||
# Note: Only building orly binary as requested
|
# Note: Only building orly binary as requested
|
||||||
# Other cmd utilities (aggregator, benchmark, convert, policytest, stresstest) are development tools
|
# Other cmd utilities (aggregator, benchmark, convert, policytest, stresstest) are development tools
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/acl"
|
"next.orly.dev/pkg/acl"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/protocol/relayinfo"
|
"next.orly.dev/pkg/protocol/relayinfo"
|
||||||
"next.orly.dev/pkg/version"
|
"next.orly.dev/pkg/version"
|
||||||
@@ -74,7 +74,7 @@ func (s *Server) HandleRelayInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Get relay identity pubkey as hex
|
// Get relay identity pubkey as hex
|
||||||
var relayPubkey string
|
var relayPubkey string
|
||||||
if skb, err := s.D.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
if skb, err := s.D.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err == nil {
|
if err := sign.InitSec(skb); err == nil {
|
||||||
relayPubkey = hex.Enc(sign.Pub())
|
relayPubkey = hex.Enc(sign.Pub())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,13 +49,37 @@ func (l *Listener) Ctx() context.Context {
|
|||||||
// writeWorker is the single goroutine that handles all writes to the websocket connection.
|
// writeWorker is the single goroutine that handles all writes to the websocket connection.
|
||||||
// This serializes all writes to prevent concurrent write panics.
|
// This serializes all writes to prevent concurrent write panics.
|
||||||
func (l *Listener) writeWorker() {
|
func (l *Listener) writeWorker() {
|
||||||
defer close(l.writeDone)
|
var channelClosed bool
|
||||||
|
defer func() {
|
||||||
|
// Only unregister write channel if connection is actually dead/closing
|
||||||
|
// Unregister if:
|
||||||
|
// 1. Context is cancelled (connection closing)
|
||||||
|
// 2. Channel was closed (connection closing)
|
||||||
|
// 3. Connection error occurred (already handled inline)
|
||||||
|
if l.ctx.Err() != nil || channelClosed {
|
||||||
|
// Connection is closing - safe to unregister
|
||||||
|
if socketPub := l.publishers.GetSocketPublisher(); socketPub != nil {
|
||||||
|
log.D.F("ws->%s write worker: unregistering write channel (connection closing)", l.remote)
|
||||||
|
socketPub.SetWriteChan(l.conn, nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Exiting for other reasons (timeout, etc.) but connection may still be alive
|
||||||
|
// Don't unregister - let the connection cleanup handle it
|
||||||
|
log.D.F("ws->%s write worker: exiting but connection may still be alive, keeping write channel registered", l.remote)
|
||||||
|
}
|
||||||
|
close(l.writeDone)
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-l.ctx.Done():
|
case <-l.ctx.Done():
|
||||||
|
// Context cancelled - connection is closing
|
||||||
|
log.D.F("ws->%s write worker: context cancelled, exiting", l.remote)
|
||||||
return
|
return
|
||||||
case req, ok := <-l.writeChan:
|
case req, ok := <-l.writeChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
// Channel closed - connection is closing
|
||||||
|
channelClosed = true
|
||||||
|
log.D.F("ws->%s write worker: write channel closed, exiting", l.remote)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
deadline := req.Deadline
|
deadline := req.Deadline
|
||||||
@@ -82,9 +106,15 @@ func (l *Listener) writeWorker() {
|
|||||||
websocket.CloseGoingAway,
|
websocket.CloseGoingAway,
|
||||||
websocket.CloseNoStatusReceived)
|
websocket.CloseNoStatusReceived)
|
||||||
if isConnectionError {
|
if isConnectionError {
|
||||||
|
// Connection is dead - unregister channel immediately
|
||||||
|
log.D.F("ws->%s write worker: connection error detected, unregistering write channel", l.remote)
|
||||||
|
if socketPub := l.publishers.GetSocketPublisher(); socketPub != nil {
|
||||||
|
socketPub.SetWriteChan(l.conn, nil)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Continue for other errors (timeouts, etc.)
|
// Continue for other errors (timeouts, etc.) - connection may still be alive
|
||||||
|
log.D.F("ws->%s write worker: non-fatal error (timeout?), continuing", l.remote)
|
||||||
} else {
|
} else {
|
||||||
writeDuration := time.Since(writeStart)
|
writeDuration := time.Since(writeStart)
|
||||||
if writeDuration > time.Millisecond*100 {
|
if writeDuration > time.Millisecond*100 {
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ func Run(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if l.paymentProcessor, err = NewPaymentProcessor(ctx, cfg, db); err != nil {
|
if l.paymentProcessor, err = NewPaymentProcessor(ctx, cfg, db); err != nil {
|
||||||
log.E.F("failed to create payment processor: %v", err)
|
// log.E.F("failed to create payment processor: %v", err)
|
||||||
// Continue without payment processor
|
// Continue without payment processor
|
||||||
} else {
|
} else {
|
||||||
if err = l.paymentProcessor.Start(); err != nil {
|
if err = l.paymentProcessor.Start(); err != nil {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/app/config"
|
"next.orly.dev/app/config"
|
||||||
"next.orly.dev/pkg/acl"
|
"next.orly.dev/pkg/acl"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/database"
|
"next.orly.dev/pkg/database"
|
||||||
"next.orly.dev/pkg/encoders/bech32encoding"
|
"next.orly.dev/pkg/encoders/bech32encoding"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
@@ -152,7 +152,7 @@ func (pp *PaymentProcessor) syncFollowList() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// signer
|
// signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ func (pp *PaymentProcessor) createExpiryWarningNote(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize signer
|
// Initialize signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return fmt.Errorf("failed to initialize signer: %w", err)
|
return fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
@@ -383,7 +383,7 @@ func (pp *PaymentProcessor) createTrialReminderNote(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize signer
|
// Initialize signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return fmt.Errorf("failed to initialize signer: %w", err)
|
return fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
@@ -530,7 +530,7 @@ func (pp *PaymentProcessor) handleNotification(
|
|||||||
if s, ok := metadata["relay_pubkey"].(string); ok && s != "" {
|
if s, ok := metadata["relay_pubkey"].(string); ok && s != "" {
|
||||||
if rpk, err := decodeAnyPubkey(s); err == nil {
|
if rpk, err := decodeAnyPubkey(s); err == nil {
|
||||||
if skb, err := pp.db.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
if skb, err := pp.db.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
||||||
var signer p256k.Signer
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.InitSec(skb); err == nil {
|
if err := signer.InitSec(skb); err == nil {
|
||||||
if !strings.EqualFold(
|
if !strings.EqualFold(
|
||||||
hex.Enc(rpk), hex.Enc(signer.Pub()),
|
hex.Enc(rpk), hex.Enc(signer.Pub()),
|
||||||
@@ -644,7 +644,7 @@ func (pp *PaymentProcessor) createPaymentNote(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize signer
|
// Initialize signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return fmt.Errorf("failed to initialize signer: %w", err)
|
return fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
@@ -738,7 +738,7 @@ func (pp *PaymentProcessor) CreateWelcomeNote(userPubkey []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize signer
|
// Initialize signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return fmt.Errorf("failed to initialize signer: %w", err)
|
return fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1025,7 +1025,7 @@ func (pp *PaymentProcessor) UpdateRelayProfile() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize signer
|
// Initialize signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.InitSec(skb); err != nil {
|
if err := sign.InitSec(skb); err != nil {
|
||||||
return fmt.Errorf("failed to initialize signer: %w", err)
|
return fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,10 +89,15 @@ func NewPublisher(c context.Context) (publisher *P) {
|
|||||||
func (p *P) Type() (typeName string) { return Type }
|
func (p *P) Type() (typeName string) { return Type }
|
||||||
|
|
||||||
// SetWriteChan stores the write channel for a websocket connection
|
// SetWriteChan stores the write channel for a websocket connection
|
||||||
|
// If writeChan is nil, the entry is removed from the map
|
||||||
func (p *P) SetWriteChan(conn *websocket.Conn, writeChan chan<- publish.WriteRequest) {
|
func (p *P) SetWriteChan(conn *websocket.Conn, writeChan chan<- publish.WriteRequest) {
|
||||||
p.Mx.Lock()
|
p.Mx.Lock()
|
||||||
defer p.Mx.Unlock()
|
defer p.Mx.Unlock()
|
||||||
p.WriteChans[conn] = writeChan
|
if writeChan == nil {
|
||||||
|
delete(p.WriteChans, conn)
|
||||||
|
} else {
|
||||||
|
p.WriteChans[conn] = writeChan
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWriteChan returns the write channel for a websocket connection
|
// GetWriteChan returns the write channel for a websocket connection
|
||||||
@@ -340,7 +345,9 @@ func (p *P) removeSubscriberId(ws *websocket.Conn, id string) {
|
|||||||
// Check the actual map after deletion, not the original reference
|
// Check the actual map after deletion, not the original reference
|
||||||
if len(p.Map[ws]) == 0 {
|
if len(p.Map[ws]) == 0 {
|
||||||
delete(p.Map, ws)
|
delete(p.Map, ws)
|
||||||
delete(p.WriteChans, ws)
|
// Don't remove write channel here - it's tied to the connection, not subscriptions
|
||||||
|
// The write channel will be removed when the connection closes (in handle-websocket.go defer)
|
||||||
|
// This allows new subscriptions to be created on the same connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/crypto/sha256"
|
"next.orly.dev/pkg/crypto/sha256"
|
||||||
"next.orly.dev/pkg/encoders/bech32encoding"
|
"next.orly.dev/pkg/encoders/bech32encoding"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
@@ -335,7 +335,7 @@ func NewAggregator(keyInput string, since, until *timestamp.T, bloomFilterFile s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create signer from private key
|
// Create signer from private key
|
||||||
signer = &p256k.Signer{}
|
signer = p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.InitSec(secretBytes); chk.E(err) {
|
if err = signer.InitSec(secretBytes); chk.E(err) {
|
||||||
return nil, fmt.Errorf("failed to initialize signer: %w", err)
|
return nil, fmt.Errorf("failed to initialize signer: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
|
||||||
"next.orly.dev/pkg/database"
|
"next.orly.dev/pkg/database"
|
||||||
"next.orly.dev/pkg/encoders/envelopes/eventenvelope"
|
"next.orly.dev/pkg/encoders/envelopes/eventenvelope"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
@@ -22,6 +21,7 @@ import (
|
|||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
"next.orly.dev/pkg/encoders/timestamp"
|
"next.orly.dev/pkg/encoders/timestamp"
|
||||||
"next.orly.dev/pkg/protocol/ws"
|
"next.orly.dev/pkg/protocol/ws"
|
||||||
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BenchmarkConfig struct {
|
type BenchmarkConfig struct {
|
||||||
@@ -167,7 +167,7 @@ func runNetworkLoad(cfg *BenchmarkConfig) {
|
|||||||
fmt.Printf("worker %d: connected to %s\n", workerID, cfg.RelayURL)
|
fmt.Printf("worker %d: connected to %s\n", workerID, cfg.RelayURL)
|
||||||
|
|
||||||
// Signer for this worker
|
// Signer for this worker
|
||||||
var keys p256k.Signer
|
keys := p256k1signer.NewP256K1Signer()
|
||||||
if err := keys.Generate(); err != nil {
|
if err := keys.Generate(); err != nil {
|
||||||
fmt.Printf("worker %d: keygen failed: %v\n", workerID, err)
|
fmt.Printf("worker %d: keygen failed: %v\n", workerID, err)
|
||||||
return
|
return
|
||||||
@@ -244,7 +244,7 @@ func runNetworkLoad(cfg *BenchmarkConfig) {
|
|||||||
ev.Content = []byte(fmt.Sprintf(
|
ev.Content = []byte(fmt.Sprintf(
|
||||||
"bench worker=%d n=%d", workerID, count,
|
"bench worker=%d n=%d", workerID, count,
|
||||||
))
|
))
|
||||||
if err := ev.Sign(&keys); err != nil {
|
if err := ev.Sign(keys); err != nil {
|
||||||
fmt.Printf("worker %d: sign error: %v\n", workerID, err)
|
fmt.Printf("worker %d: sign error: %v\n", workerID, err)
|
||||||
ev.Free()
|
ev.Free()
|
||||||
continue
|
continue
|
||||||
@@ -960,7 +960,7 @@ func (b *Benchmark) generateEvents(count int) []*event.E {
|
|||||||
now := timestamp.Now()
|
now := timestamp.Now()
|
||||||
|
|
||||||
// Generate a keypair for signing all events
|
// Generate a keypair for signing all events
|
||||||
var keys p256k.Signer
|
keys := p256k1signer.NewP256K1Signer()
|
||||||
if err := keys.Generate(); err != nil {
|
if err := keys.Generate(); err != nil {
|
||||||
log.Fatalf("Failed to generate keys for benchmark events: %v", err)
|
log.Fatalf("Failed to generate keys for benchmark events: %v", err)
|
||||||
}
|
}
|
||||||
@@ -983,7 +983,7 @@ func (b *Benchmark) generateEvents(count int) []*event.E {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Properly sign the event instead of generating fake signatures
|
// Properly sign the event instead of generating fake signatures
|
||||||
if err := ev.Sign(&keys); err != nil {
|
if err := ev.Sign(keys); err != nil {
|
||||||
log.Fatalf("Failed to sign event %d: %v", i, err)
|
log.Fatalf("Failed to sign event %d: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -44,7 +44,7 @@ func main() {
|
|||||||
log.E.F("failed to decode allowed secret key: %v", err)
|
log.E.F("failed to decode allowed secret key: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
allowedSigner := &p256k.Signer{}
|
allowedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err = allowedSigner.InitSec(allowedSecBytes); chk.E(err) {
|
if err = allowedSigner.InitSec(allowedSecBytes); chk.E(err) {
|
||||||
log.E.F("failed to initialize allowed signer: %v", err)
|
log.E.F("failed to initialize allowed signer: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -55,7 +55,7 @@ func main() {
|
|||||||
log.E.F("failed to decode unauthorized secret key: %v", err)
|
log.E.F("failed to decode unauthorized secret key: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
unauthorizedSigner := &p256k.Signer{}
|
unauthorizedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err = unauthorizedSigner.InitSec(unauthorizedSecBytes); chk.E(err) {
|
if err = unauthorizedSigner.InitSec(unauthorizedSecBytes); chk.E(err) {
|
||||||
log.E.F("failed to initialize unauthorized signer: %v", err)
|
log.E.F("failed to initialize unauthorized signer: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -136,7 +136,7 @@ func main() {
|
|||||||
fmt.Println("\n✅ All tests passed!")
|
fmt.Println("\n✅ All tests passed!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWriteEvent(ctx context.Context, url string, kindNum uint16, eventSigner, authSigner *p256k.Signer) error {
|
func testWriteEvent(ctx context.Context, url string, kindNum uint16, eventSigner, authSigner *p256k1signer.P256K1Signer) error {
|
||||||
rl, err := ws.RelayConnect(ctx, url)
|
rl, err := ws.RelayConnect(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("connect error: %w", err)
|
return fmt.Errorf("connect error: %w", err)
|
||||||
@@ -192,7 +192,7 @@ func testWriteEvent(ctx context.Context, url string, kindNum uint16, eventSigner
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWriteEventUnauthenticated(ctx context.Context, url string, kindNum uint16, eventSigner *p256k.Signer) error {
|
func testWriteEventUnauthenticated(ctx context.Context, url string, kindNum uint16, eventSigner *p256k1signer.P256K1Signer) error {
|
||||||
rl, err := ws.RelayConnect(ctx, url)
|
rl, err := ws.RelayConnect(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("connect error: %w", err)
|
return fmt.Errorf("connect error: %w", err)
|
||||||
@@ -227,7 +227,7 @@ func testWriteEventUnauthenticated(ctx context.Context, url string, kindNum uint
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testReadEvent(ctx context.Context, url string, kindNum uint16, authSigner *p256k.Signer) error {
|
func testReadEvent(ctx context.Context, url string, kindNum uint16, authSigner *p256k1signer.P256K1Signer) error {
|
||||||
rl, err := ws.RelayConnect(ctx, url)
|
rl, err := ws.RelayConnect(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("connect error: %w", err)
|
return fmt.Errorf("connect error: %w", err)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/kind"
|
"next.orly.dev/pkg/encoders/kind"
|
||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
@@ -29,7 +29,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer rl.Close()
|
defer rl.Close()
|
||||||
|
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.Generate(); chk.E(err) {
|
if err = signer.Generate(); chk.E(err) {
|
||||||
log.E.F("signer generate error: %v", err)
|
log.E.F("signer generate error: %v", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/envelopes/eventenvelope"
|
"next.orly.dev/pkg/encoders/envelopes/eventenvelope"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/event/examples"
|
"next.orly.dev/pkg/encoders/event/examples"
|
||||||
@@ -35,7 +35,7 @@ func randomHex(n int) string {
|
|||||||
return hex.Enc(b)
|
return hex.Enc(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeEvent(rng *rand.Rand, signer *p256k.Signer) (*event.E, error) {
|
func makeEvent(rng *rand.Rand, signer *p256k1signer.P256K1Signer) (*event.E, error) {
|
||||||
ev := &event.E{
|
ev := &event.E{
|
||||||
CreatedAt: time.Now().Unix(),
|
CreatedAt: time.Now().Unix(),
|
||||||
Kind: kind.TextNote.K,
|
Kind: kind.TextNote.K,
|
||||||
@@ -293,7 +293,7 @@ func publisherWorker(
|
|||||||
src := rand.NewSource(time.Now().UnixNano() ^ int64(id<<16))
|
src := rand.NewSource(time.Now().UnixNano() ^ int64(id<<16))
|
||||||
rng := rand.New(src)
|
rng := rand.New(src)
|
||||||
// Generate and reuse signing key per worker
|
// Generate and reuse signing key per worker
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
log.E.F("worker %d: signer generate error: %v", id, err)
|
log.E.F("worker %d: signer generate error: %v", id, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"next.orly.dev/pkg/acl"
|
"next.orly.dev/pkg/acl"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/database"
|
"next.orly.dev/pkg/database"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -59,8 +59,8 @@ func testSetup(t *testing.T) (*Server, func()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createTestKeypair creates a test keypair for signing events
|
// createTestKeypair creates a test keypair for signing events
|
||||||
func createTestKeypair(t *testing.T) ([]byte, *p256k.Signer) {
|
func createTestKeypair(t *testing.T) ([]byte, *p256k1signer.P256K1Signer) {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
t.Fatalf("Failed to generate keypair: %v", err)
|
t.Fatalf("Failed to generate keypair: %v", err)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ func createTestKeypair(t *testing.T) ([]byte, *p256k.Signer) {
|
|||||||
|
|
||||||
// createAuthEvent creates a valid kind 24242 authorization event
|
// createAuthEvent creates a valid kind 24242 authorization event
|
||||||
func createAuthEvent(
|
func createAuthEvent(
|
||||||
t *testing.T, signer *p256k.Signer, verb string,
|
t *testing.T, signer *p256k1signer.P256K1Signer, verb string,
|
||||||
sha256Hash []byte, expiresIn int64,
|
sha256Hash []byte, expiresIn int64,
|
||||||
) *event.E {
|
) *event.E {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package encryption
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"lukechampine.com/frand"
|
"lukechampine.com/frand"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,8 +13,8 @@ func createTestConversationKey() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createTestKeyPair creates a key pair for ECDH testing
|
// createTestKeyPair creates a key pair for ECDH testing
|
||||||
func createTestKeyPair() (*p256k.Signer, []byte) {
|
func createTestKeyPair() (*p256k1signer.P256K1Signer, []byte) {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ import (
|
|||||||
"golang.org/x/crypto/hkdf"
|
"golang.org/x/crypto/hkdf"
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/errorf"
|
"lol.mleku.dev/errorf"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/crypto/sha256"
|
"next.orly.dev/pkg/crypto/sha256"
|
||||||
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
"next.orly.dev/pkg/interfaces/signer"
|
||||||
"next.orly.dev/pkg/utils"
|
"next.orly.dev/pkg/utils"
|
||||||
)
|
)
|
||||||
@@ -176,11 +177,16 @@ func GenerateConversationKeyFromHex(pkh, skh string) (ck []byte, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var sign signer.I
|
var sign signer.I
|
||||||
if sign, err = p256k.NewSecFromHex(skh); chk.E(err) {
|
sign = p256k1signer.NewP256K1Signer()
|
||||||
|
var sk []byte
|
||||||
|
if sk, err = hex.Dec(skh); chk.E(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = sign.InitSec(sk); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var pk []byte
|
var pk []byte
|
||||||
if pk, err = p256k.HexToBin(pkh); chk.E(err) {
|
if pk, err = hex.Dec(pkh); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var shared []byte
|
var shared []byte
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/ec/schnorr"
|
"next.orly.dev/pkg/crypto/ec/schnorr"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/utils"
|
"next.orly.dev/pkg/utils"
|
||||||
)
|
)
|
||||||
@@ -17,7 +17,7 @@ var GeneratePrivateKey = func() string { return GenerateSecretKeyHex() }
|
|||||||
|
|
||||||
// GenerateSecretKey creates a new secret key and returns the bytes of the secret.
|
// GenerateSecretKey creates a new secret key and returns the bytes of the secret.
|
||||||
func GenerateSecretKey() (skb []byte, err error) {
|
func GenerateSecretKey() (skb []byte, err error) {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.Generate(); chk.E(err) {
|
if err = signer.Generate(); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ func GetPublicKeyHex(sk string) (pk string, err error) {
|
|||||||
if b, err = hex.Dec(sk); chk.E(err) {
|
if b, err = hex.Dec(sk); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.InitSec(b); chk.E(err) {
|
if err = signer.InitSec(b); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ func GetPublicKeyHex(sk string) (pk string, err error) {
|
|||||||
|
|
||||||
// SecretBytesToPubKeyHex generates a public key from secret key bytes.
|
// SecretBytesToPubKeyHex generates a public key from secret key bytes.
|
||||||
func SecretBytesToPubKeyHex(skb []byte) (pk string, err error) {
|
func SecretBytesToPubKeyHex(skb []byte) (pk string, err error) {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.InitSec(skb); chk.E(err) {
|
if err = signer.InitSec(skb); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
# p256k1
|
|
||||||
|
|
||||||
This is a library that uses the `bitcoin-core` optimized secp256k1 elliptic
|
|
||||||
curve signatures library for `nostr` schnorr signatures.
|
|
||||||
|
|
||||||
If you need to build it without `libsecp256k1` C library, you must disable cgo:
|
|
||||||
|
|
||||||
export CGO_ENABLED='0'
|
|
||||||
|
|
||||||
This enables the fallback `btcec` pure Go library to be used in its place. This
|
|
||||||
CGO setting is not default for Go, so it must be set in order to disable this.
|
|
||||||
|
|
||||||
The standard `libsecp256k1-0` and `libsecp256k1-dev` available through the
|
|
||||||
ubuntu dpkg repositories do not include support for the BIP-340 schnorr
|
|
||||||
signatures or the ECDH X-only shared secret generation algorithm, so you must
|
|
||||||
follow the following instructions to get the benefits of using this library. It
|
|
||||||
is 4x faster at signing and generating shared secrets so it is a must if your
|
|
||||||
intention is to use it for high throughput systems like a network transport.
|
|
||||||
|
|
||||||
The easy way to install it, if you have ubuntu/debian, is the script
|
|
||||||
[../ubuntu_install_libsecp256k1.sh](../../../scripts/ubuntu_install_libsecp256k1.sh),
|
|
||||||
it
|
|
||||||
handles the dependencies and runs the build all in one step for you. Note that
|
|
||||||
it
|
|
||||||
|
|
||||||
For ubuntu, you need these:
|
|
||||||
|
|
||||||
sudo apt -y install build-essential autoconf libtool
|
|
||||||
|
|
||||||
For other linux distributions, the process is the same but the dependencies are
|
|
||||||
likely different. The main thing is it requires make, gcc/++, autoconf and
|
|
||||||
libtool to run. The most important thing to point out is that you must enable
|
|
||||||
the schnorr signatures feature, and ECDH.
|
|
||||||
|
|
||||||
The directory `p256k/secp256k1` needs to be initialized, built and installed,
|
|
||||||
like so:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd secp256k1
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
```
|
|
||||||
|
|
||||||
Then to build, you can refer to the [instructions](./secp256k1/README.md) or
|
|
||||||
just use the default autotools:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-module-schnorrsig --enable-module-ecdh --prefix=/usr
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
On WSL2 you may have to attend to various things to make this work, setting up
|
|
||||||
your basic locale (uncomment one or more in `/etc/locale.gen`, and run
|
|
||||||
`locale-gen`), installing the basic build tools (build-essential or base-devel)
|
|
||||||
and of course git, curl, wget, libtool and
|
|
||||||
autoconf.
|
|
||||||
|
|
||||||
## ECDH
|
|
||||||
|
|
||||||
TODO: Currently the use of the libsecp256k1 library for ECDH, used in nip-04 and
|
|
||||||
nip-44 encryption is not enabled, because the default version uses the Y
|
|
||||||
coordinate and this is incorrect for nostr. It will be enabled soon... for now
|
|
||||||
it is done with the `btcec` fallback version. This is slower, however previous
|
|
||||||
tests have shown that this ECDH library is fast enough to enable 8mb/s
|
|
||||||
throughput per CPU thread when used to generate a distinct secret for TCP
|
|
||||||
packets. The C library will likely raise this to 20mb/s or more.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
//go:build !cgo
|
|
||||||
|
|
||||||
package p256k
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/log"
|
|
||||||
p256k1signer "p256k1.mleku.dev/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.T.Ln("using p256k1.mleku.dev/signer (pure Go/Btcec)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signer is an alias for the BtcecSigner type from p256k1.mleku.dev/signer (btcec version).
|
|
||||||
// This is used when CGO is not available.
|
|
||||||
type Signer = p256k1signer.BtcecSigner
|
|
||||||
|
|
||||||
// Keygen is an alias for the P256K1Gen type from p256k1.mleku.dev/signer (btcec version).
|
|
||||||
type Keygen = p256k1signer.P256K1Gen
|
|
||||||
|
|
||||||
var NewKeygen = p256k1signer.NewP256K1Gen
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
//go:build !cgo
|
|
||||||
|
|
||||||
// Package btcec implements the signer.I interface for signatures and ECDH with nostr.
|
|
||||||
package btcec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"lol.mleku.dev/errorf"
|
|
||||||
"next.orly.dev/pkg/crypto/ec/schnorr"
|
|
||||||
"next.orly.dev/pkg/crypto/ec/secp256k1"
|
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Signer is an implementation of signer.I that uses the btcec library.
|
|
||||||
type Signer struct {
|
|
||||||
SecretKey *secp256k1.SecretKey
|
|
||||||
PublicKey *secp256k1.PublicKey
|
|
||||||
BTCECSec *secp256k1.SecretKey
|
|
||||||
pkb, skb []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ signer.I = &Signer{}
|
|
||||||
|
|
||||||
// Generate creates a new Signer.
|
|
||||||
func (s *Signer) Generate() (err error) {
|
|
||||||
if s.SecretKey, err = secp256k1.GenerateSecretKey(); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.skb = s.SecretKey.Serialize()
|
|
||||||
s.BTCECSec = secp256k1.PrivKeyFromBytes(s.skb)
|
|
||||||
s.PublicKey = s.SecretKey.PubKey()
|
|
||||||
s.pkb = schnorr.SerializePubKey(s.PublicKey)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitSec initialises a Signer using raw secret key bytes.
|
|
||||||
func (s *Signer) InitSec(sec []byte) (err error) {
|
|
||||||
if len(sec) != secp256k1.SecKeyBytesLen {
|
|
||||||
err = errorf.E("sec key must be %d bytes", secp256k1.SecKeyBytesLen)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.skb = sec
|
|
||||||
s.SecretKey = secp256k1.SecKeyFromBytes(sec)
|
|
||||||
s.PublicKey = s.SecretKey.PubKey()
|
|
||||||
s.pkb = schnorr.SerializePubKey(s.PublicKey)
|
|
||||||
s.BTCECSec = secp256k1.PrivKeyFromBytes(s.skb)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitPub initializes a signature verifier Signer from raw public key bytes.
|
|
||||||
func (s *Signer) InitPub(pub []byte) (err error) {
|
|
||||||
if s.PublicKey, err = schnorr.ParsePubKey(pub); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.pkb = pub
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sec returns the raw secret key bytes.
|
|
||||||
func (s *Signer) Sec() (b []byte) {
|
|
||||||
if s == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return s.skb
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pub returns the raw BIP-340 schnorr public key bytes.
|
|
||||||
func (s *Signer) Pub() (b []byte) {
|
|
||||||
if s == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return s.pkb
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign a message with the Signer. Requires an initialised secret key.
|
|
||||||
func (s *Signer) Sign(msg []byte) (sig []byte, err error) {
|
|
||||||
if s.SecretKey == nil {
|
|
||||||
err = errorf.E("btcec: Signer not initialized")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var si *schnorr.Signature
|
|
||||||
if si, err = schnorr.Sign(s.SecretKey, msg); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sig = si.Serialize()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify a message signature, only requires the public key is initialised.
|
|
||||||
func (s *Signer) Verify(msg, sig []byte) (valid bool, err error) {
|
|
||||||
if s.PublicKey == nil {
|
|
||||||
err = errorf.E("btcec: Pubkey not initialized")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// First try to verify using the schnorr package
|
|
||||||
var si *schnorr.Signature
|
|
||||||
if si, err = schnorr.ParseSignature(sig); err == nil {
|
|
||||||
valid = si.Verify(msg, s.PublicKey)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If parsing the signature failed, log it at debug level
|
|
||||||
chk.D(err)
|
|
||||||
|
|
||||||
// If the signature is exactly 64 bytes, try to verify it directly
|
|
||||||
// This is to handle signatures created by p256k.Signer which uses libsecp256k1
|
|
||||||
if len(sig) == schnorr.SignatureSize {
|
|
||||||
// Create a new signature with the raw bytes
|
|
||||||
var r secp256k1.FieldVal
|
|
||||||
var sScalar secp256k1.ModNScalar
|
|
||||||
|
|
||||||
// Split the signature into r and s components
|
|
||||||
if overflow := r.SetByteSlice(sig[0:32]); !overflow {
|
|
||||||
sScalar.SetByteSlice(sig[32:64])
|
|
||||||
|
|
||||||
// Create a new signature and verify it
|
|
||||||
newSig := schnorr.NewSignature(&r, &sScalar)
|
|
||||||
valid = newSig.Verify(msg, s.PublicKey)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all verification methods failed, return an error
|
|
||||||
err = errorf.E(
|
|
||||||
"failed to verify signature:\n%d %s", len(sig), sig,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero wipes the bytes of the secret key.
|
|
||||||
func (s *Signer) Zero() { s.SecretKey.Key.Zero() }
|
|
||||||
|
|
||||||
// ECDH creates a shared secret from a secret key and a provided public key bytes. It is advised
|
|
||||||
// to hash this result for security reasons.
|
|
||||||
func (s *Signer) ECDH(pubkeyBytes []byte) (secret []byte, err error) {
|
|
||||||
var pub *secp256k1.PublicKey
|
|
||||||
if pub, err = secp256k1.ParsePubKey(
|
|
||||||
append(
|
|
||||||
[]byte{0x02}, pubkeyBytes...,
|
|
||||||
),
|
|
||||||
); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
secret = secp256k1.GenerateSharedSecret(s.BTCECSec, pub)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keygen implements a key generator. Used for such things as vanity npub mining.
|
|
||||||
type Keygen struct {
|
|
||||||
Signer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a new key pair. If the result is suitable, the embedded Signer can have its contents
|
|
||||||
// extracted.
|
|
||||||
func (k *Keygen) Generate() (pubBytes []byte, err error) {
|
|
||||||
if k.Signer.SecretKey, err = secp256k1.GenerateSecretKey(); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
k.Signer.PublicKey = k.SecretKey.PubKey()
|
|
||||||
k.Signer.pkb = schnorr.SerializePubKey(k.Signer.PublicKey)
|
|
||||||
pubBytes = k.Signer.pkb
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyPairBytes returns the raw bytes of the embedded Signer.
|
|
||||||
func (k *Keygen) KeyPairBytes() (secBytes, cmprPubBytes []byte) {
|
|
||||||
return k.Signer.SecretKey.Serialize(), k.Signer.PublicKey.SerializeCompressed()
|
|
||||||
}
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
//go:build !cgo
|
|
||||||
|
|
||||||
package btcec_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"lol.mleku.dev/log"
|
|
||||||
"next.orly.dev/pkg/crypto/p256k/btcec"
|
|
||||||
"next.orly.dev/pkg/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSigner_Generate(t *testing.T) {
|
|
||||||
for _ = range 100 {
|
|
||||||
var err error
|
|
||||||
signer := &btcec.Signer{}
|
|
||||||
var skb []byte
|
|
||||||
if err = signer.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
skb = signer.Sec()
|
|
||||||
if err = signer.InitSec(skb); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func TestBTCECSignerVerify(t *testing.T) {
|
|
||||||
// evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
//
|
|
||||||
// // Create both btcec and p256k signers
|
|
||||||
// btcecSigner := &btcec.Signer{}
|
|
||||||
// p256kSigner := &p256k.Signer{}
|
|
||||||
//
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// var valid bool
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// } else {
|
|
||||||
// // We know ev.Verify() works, so we'll use it as a reference
|
|
||||||
// if valid, err = ev.Verify(); chk.E(err) || !valid {
|
|
||||||
// t.Errorf("invalid signature\n%s", b)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Get the ID from the event
|
|
||||||
// storedID := ev.ID
|
|
||||||
// calculatedID := ev.GetIDBytes()
|
|
||||||
//
|
|
||||||
// // Check if the stored ID matches the calculated ID
|
|
||||||
// if !utils.FastEqual(storedID, calculatedID) {
|
|
||||||
// log.D.Ln("Event ID mismatch: stored ID doesn't match calculated ID")
|
|
||||||
// // Use the calculated ID for verification as ev.Verify() would do
|
|
||||||
// ev.ID = calculatedID
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if len(ev.ID) != sha256.Size {
|
|
||||||
// t.Errorf("id should be 32 bytes, got %d", len(ev.ID))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Initialize both signers with the same public key
|
|
||||||
// if err = btcecSigner.InitPub(ev.Pubkey); chk.E(err) {
|
|
||||||
// t.Errorf("failed to init btcec pub key: %s\n%0x", err, b)
|
|
||||||
// }
|
|
||||||
// if err = p256kSigner.InitPub(ev.Pubkey); chk.E(err) {
|
|
||||||
// t.Errorf("failed to init p256k pub key: %s\n%0x", err, b)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // First try to verify with btcec.Signer
|
|
||||||
// if valid, err = btcecSigner.Verify(ev.ID, ev.Sig); err == nil && valid {
|
|
||||||
// // If btcec.Signer verification succeeds, great!
|
|
||||||
// log.D.Ln("btcec.Signer verification succeeded")
|
|
||||||
// } else {
|
|
||||||
// // If btcec.Signer verification fails, try with p256k.Signer
|
|
||||||
// // Use chk.T(err) like ev.Verify() does
|
|
||||||
// if valid, err = p256kSigner.Verify(ev.ID, ev.Sig); chk.T(err) {
|
|
||||||
// // If there's an error, log it but don't fail the test
|
|
||||||
// log.D.Ln("p256k.Signer verification error:", err)
|
|
||||||
// } else if !valid {
|
|
||||||
// // Only fail the test if both verifications fail
|
|
||||||
// t.Errorf(
|
|
||||||
// "invalid signature for pub %0x %0x %0x", ev.Pubkey, ev.ID,
|
|
||||||
// ev.Sig,
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// log.D.Ln("p256k.Signer verification succeeded where btcec.Signer failed")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestBTCECSignerSign(t *testing.T) {
|
|
||||||
// evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
// signer := &btcec.Signer{}
|
|
||||||
// var skb []byte
|
|
||||||
// if err = signer.Generate(); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// skb = signer.Sec()
|
|
||||||
// if err = signer.InitSec(skb); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// verifier := &btcec.Signer{}
|
|
||||||
// pkb := signer.Pub()
|
|
||||||
// if err = verifier.InitPub(pkb); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// counter := 0
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// counter++
|
|
||||||
// if counter > 1000 {
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// }
|
|
||||||
// evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// var valid bool
|
|
||||||
// sig := make([]byte, schnorr.SignatureSize)
|
|
||||||
// for _, ev := range evs {
|
|
||||||
// ev.Pubkey = pkb
|
|
||||||
// id := ev.GetIDBytes()
|
|
||||||
// if sig, err = signer.Sign(id); chk.E(err) {
|
|
||||||
// t.Errorf("failed to sign: %s\n%0x", err, id)
|
|
||||||
// }
|
|
||||||
// if valid, err = verifier.Verify(id, sig); chk.E(err) {
|
|
||||||
// t.Errorf("failed to verify: %s\n%0x", err, id)
|
|
||||||
// }
|
|
||||||
// if !valid {
|
|
||||||
// t.Errorf("invalid signature")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// signer.Zero()
|
|
||||||
// }
|
|
||||||
|
|
||||||
func TestBTCECECDH(t *testing.T) {
|
|
||||||
n := time.Now()
|
|
||||||
var err error
|
|
||||||
var counter int
|
|
||||||
const total = 50
|
|
||||||
for _ = range total {
|
|
||||||
s1 := new(btcec.Signer)
|
|
||||||
if err = s1.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
s2 := new(btcec.Signer)
|
|
||||||
if err = s2.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for _ = range total {
|
|
||||||
var secret1, secret2 []byte
|
|
||||||
if secret1, err = s1.ECDH(s2.Pub()); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if secret2, err = s2.ECDH(s1.Pub()); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !utils.FastEqual(secret1, secret2) {
|
|
||||||
counter++
|
|
||||||
t.Errorf(
|
|
||||||
"ECDH generation failed to work in both directions, %x %x",
|
|
||||||
secret1,
|
|
||||||
secret2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a := time.Now()
|
|
||||||
duration := a.Sub(n)
|
|
||||||
log.I.Ln(
|
|
||||||
"errors", counter, "total", total, "time", duration, "time/op",
|
|
||||||
int(duration/total),
|
|
||||||
"ops/sec", int(time.Second)/int(duration/total),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//go:build !cgo
|
|
||||||
|
|
||||||
package btcec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewSecFromHex[V []byte | string](skh V) (sign signer.I, err error) {
|
|
||||||
sk := make([]byte, len(skh)/2)
|
|
||||||
if _, err = hex.DecBytes(sk, []byte(skh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = &Signer{}
|
|
||||||
if err = sign.InitSec(sk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPubFromHex[V []byte | string](pkh V) (sign signer.I, err error) {
|
|
||||||
pk := make([]byte, len(pkh)/2)
|
|
||||||
if _, err = hex.DecBytes(pk, []byte(pkh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = &Signer{}
|
|
||||||
if err = sign.InitPub(pk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func HexToBin(hexStr string) (b []byte, err error) {
|
|
||||||
b = make([]byte, len(hexStr)/2)
|
|
||||||
if _, err = hex.DecBytes(b, []byte(hexStr)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
// Package p256k provides a signer interface that uses p256k1.mleku.dev library for
|
|
||||||
// fast signature creation and verification of BIP-340 nostr X-only signatures and
|
|
||||||
// public keys, and ECDH.
|
|
||||||
//
|
|
||||||
// The package provides type aliases to p256k1.mleku.dev/signer:
|
|
||||||
// - cgo: Uses the CGO-optimized version from p256k1.mleku.dev
|
|
||||||
// - btcec: Uses the btcec version from p256k1.mleku.dev
|
|
||||||
// - default: Uses the pure Go version from p256k1.mleku.dev
|
|
||||||
package p256k
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//go:build !cgo
|
|
||||||
|
|
||||||
package p256k
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
|
||||||
p256k1signer "p256k1.mleku.dev/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewSecFromHex[V []byte | string](skh V) (sign signer.I, err error) {
|
|
||||||
sk := make([]byte, len(skh)/2)
|
|
||||||
if _, err = hex.DecBytes(sk, []byte(skh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = p256k1signer.NewBtcecSigner()
|
|
||||||
if err = sign.InitSec(sk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPubFromHex[V []byte | string](pkh V) (sign signer.I, err error) {
|
|
||||||
pk := make([]byte, len(pkh)/2)
|
|
||||||
if _, err = hex.DecBytes(pk, []byte(pkh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = p256k1signer.NewBtcecSigner()
|
|
||||||
if err = sign.InitPub(pk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func HexToBin(hexStr string) (b []byte, err error) {
|
|
||||||
if b, err = hex.DecAppend(b, []byte(hexStr)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//go:build cgo
|
|
||||||
|
|
||||||
package p256k
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
|
||||||
p256k1signer "p256k1.mleku.dev/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewSecFromHex[V []byte | string](skh V) (sign signer.I, err error) {
|
|
||||||
sk := make([]byte, len(skh)/2)
|
|
||||||
if _, err = hex.DecBytes(sk, []byte(skh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = p256k1signer.NewP256K1Signer()
|
|
||||||
if err = sign.InitSec(sk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPubFromHex[V []byte | string](pkh V) (sign signer.I, err error) {
|
|
||||||
pk := make([]byte, len(pkh)/2)
|
|
||||||
if _, err = hex.DecBytes(pk, []byte(pkh)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sign = p256k1signer.NewP256K1Signer()
|
|
||||||
if err = sign.InitPub(pk); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func HexToBin(hexStr string) (b []byte, err error) {
|
|
||||||
if b, err = hex.DecAppend(b, []byte(hexStr)); chk.E(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
//go:build cgo
|
|
||||||
|
|
||||||
package p256k
|
|
||||||
|
|
||||||
import (
|
|
||||||
"lol.mleku.dev/log"
|
|
||||||
p256k1signer "p256k1.mleku.dev/signer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.T.Ln("using p256k1.mleku.dev/signer (CGO)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signer is an alias for the P256K1Signer type from p256k1.mleku.dev/signer (cgo version).
|
|
||||||
type Signer = p256k1signer.P256K1Signer
|
|
||||||
|
|
||||||
// Keygen is an alias for the P256K1Gen type from p256k1.mleku.dev/signer (cgo version).
|
|
||||||
type Keygen = p256k1signer.P256K1Gen
|
|
||||||
|
|
||||||
var NewKeygen = p256k1signer.NewP256K1Gen
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
//go:build cgo
|
|
||||||
|
|
||||||
package p256k_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
|
||||||
"lol.mleku.dev/log"
|
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
|
||||||
"next.orly.dev/pkg/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSigner_Generate(t *testing.T) {
|
|
||||||
for _ = range 10000 {
|
|
||||||
var err error
|
|
||||||
sign := &p256k.Signer{}
|
|
||||||
var skb []byte
|
|
||||||
if err = sign.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
skb = sign.Sec()
|
|
||||||
if err = sign.InitSec(skb); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func TestSignerVerify(t *testing.T) {
|
|
||||||
// // evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
// signer := &p256k.Signer{}
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// var valid bool
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// bc := make([]byte, 0, len(b))
|
|
||||||
// bc = append(bc, b...)
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// } else {
|
|
||||||
// if valid, err = ev.Verify(); chk.T(err) || !valid {
|
|
||||||
// t.Errorf("invalid signature\n%s", bc)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// id := ev.GetIDBytes()
|
|
||||||
// if len(id) != sha256.Size {
|
|
||||||
// t.Errorf("id should be 32 bytes, got %d", len(id))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if err = signer.InitPub(ev.Pubkey); chk.T(err) {
|
|
||||||
// t.Errorf("failed to init pub key: %s\n%0x", err, ev.Pubkey)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if valid, err = signer.Verify(id, ev.Sig); chk.E(err) {
|
|
||||||
// t.Errorf("failed to verify: %s\n%0x", err, ev.ID)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if !valid {
|
|
||||||
// t.Errorf(
|
|
||||||
// "invalid signature for\npub %0x\neid %0x\nsig %0x\n%s",
|
|
||||||
// ev.Pubkey, id, ev.Sig, bc,
|
|
||||||
// )
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// // fmt.Printf("%s\n", bc)
|
|
||||||
// // evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestSignerSign(t *testing.T) {
|
|
||||||
// evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
// signer := &p256k.Signer{}
|
|
||||||
// var skb, pkb []byte
|
|
||||||
// if skb, pkb, _, _, err = p256k.Generate(); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// log.I.S(skb, pkb)
|
|
||||||
// if err = signer.InitSec(skb); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// verifier := &p256k.Signer{}
|
|
||||||
// if err = verifier.InitPub(pkb); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// }
|
|
||||||
// evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// var valid bool
|
|
||||||
// sig := make([]byte, schnorr.SignatureSize)
|
|
||||||
// for _, ev := range evs {
|
|
||||||
// ev.Pubkey = pkb
|
|
||||||
// id := ev.GetIDBytes()
|
|
||||||
// if sig, err = signer.Sign(id); chk.E(err) {
|
|
||||||
// t.Errorf("failed to sign: %s\n%0x", err, id)
|
|
||||||
// }
|
|
||||||
// if valid, err = verifier.Verify(id, sig); chk.E(err) {
|
|
||||||
// t.Errorf("failed to verify: %s\n%0x", err, id)
|
|
||||||
// }
|
|
||||||
// if !valid {
|
|
||||||
// t.Errorf("invalid signature")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// signer.Zero()
|
|
||||||
// }
|
|
||||||
|
|
||||||
func TestECDH(t *testing.T) {
|
|
||||||
n := time.Now()
|
|
||||||
var err error
|
|
||||||
var s1, s2 signer.I
|
|
||||||
var counter int
|
|
||||||
const total = 100
|
|
||||||
for _ = range total {
|
|
||||||
s1, s2 = &p256k.Signer{}, &p256k.Signer{}
|
|
||||||
if err = s1.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for _ = range total {
|
|
||||||
if err = s2.Generate(); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
var secret1, secret2 []byte
|
|
||||||
if secret1, err = s1.ECDH(s2.Pub()); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if secret2, err = s2.ECDH(s1.Pub()); chk.E(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !utils.FastEqual(secret1, secret2) {
|
|
||||||
counter++
|
|
||||||
t.Errorf(
|
|
||||||
"ECDH generation failed to work in both directions, %x %x",
|
|
||||||
secret1,
|
|
||||||
secret2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a := time.Now()
|
|
||||||
duration := a.Sub(n)
|
|
||||||
log.I.Ln(
|
|
||||||
"errors", counter, "total", total*total, "time", duration, "time/op",
|
|
||||||
duration/total/total, "ops/sec",
|
|
||||||
float64(time.Second)/float64(duration/total/total),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
//go:build cgo
|
|
||||||
|
|
||||||
package p256k_test
|
|
||||||
|
|
||||||
// func TestVerify(t *testing.T) {
|
|
||||||
// evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// var valid bool
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// } else {
|
|
||||||
// if valid, err = ev.Verify(); chk.E(err) || !valid {
|
|
||||||
// t.Errorf("btcec: invalid signature\n%s", b)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// id := ev.GetIDBytes()
|
|
||||||
// if len(id) != sha256.Size {
|
|
||||||
// t.Errorf("id should be 32 bytes, got %d", len(id))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if err = p256k.VerifyFromBytes(id, ev.Sig, ev.Pubkey); chk.E(err) {
|
|
||||||
// t.Error(err)
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestSign(t *testing.T) {
|
|
||||||
// evs := make([]*event.E, 0, 10000)
|
|
||||||
// scanner := bufio.NewScanner(bytes.NewBuffer(examples.Cache))
|
|
||||||
// buf := make([]byte, 1_000_000)
|
|
||||||
// scanner.Buffer(buf, len(buf))
|
|
||||||
// var err error
|
|
||||||
// var sec1 *p256k.Sec
|
|
||||||
// var pub1 *p256k.XPublicKey
|
|
||||||
// var pb []byte
|
|
||||||
// if _, pb, sec1, pub1, err = p256k.Generate(); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// for scanner.Scan() {
|
|
||||||
// b := scanner.Bytes()
|
|
||||||
// ev := event.New()
|
|
||||||
// if _, err = ev.Unmarshal(b); chk.E(err) {
|
|
||||||
// t.Errorf("failed to marshal\n%s", b)
|
|
||||||
// }
|
|
||||||
// evs = append(evs, ev)
|
|
||||||
// }
|
|
||||||
// sig := make([]byte, schnorr.SignatureSize)
|
|
||||||
// for _, ev := range evs {
|
|
||||||
// ev.Pubkey = pb
|
|
||||||
// var uid *p256k.Uchar
|
|
||||||
// if uid, err = p256k.Msg(ev.GetIDBytes()); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// if sig, err = p256k.Sign(uid, sec1.Sec()); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// ev.Sig = sig
|
|
||||||
// var usig *p256k.Uchar
|
|
||||||
// if usig, err = p256k.Sig(sig); chk.E(err) {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// if !p256k.Verify(uid, usig, pub1.Key) {
|
|
||||||
// t.Errorf("invalid signature")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// p256k.Zero(&sec1.Key)
|
|
||||||
// }
|
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/database/indexes/types"
|
"next.orly.dev/pkg/database/indexes/types"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/event/examples"
|
"next.orly.dev/pkg/encoders/event/examples"
|
||||||
@@ -73,7 +73,7 @@ func BenchmarkSaveEvent(b *testing.B) {
|
|||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
// Create a simple test event
|
// Create a simple test event
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -25,7 +25,7 @@ func TestMultipleParameterizedReplaceableEvents(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/encoders/kind"
|
"next.orly.dev/pkg/encoders/kind"
|
||||||
@@ -44,7 +44,7 @@ func TestQueryEventsBySearchTerms(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// signer for all events
|
// signer for all events
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatalf("signer generate: %v", err)
|
t.Fatalf("signer generate: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/event/examples"
|
"next.orly.dev/pkg/encoders/event/examples"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
@@ -198,7 +198,7 @@ func TestReplaceableEventsAndDeletion(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
// Test querying for replaced events by ID
|
// Test querying for replaced events by ID
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@ func TestParameterizedReplaceableEventsAndDeletion(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/errorf"
|
"lol.mleku.dev/errorf"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/event/examples"
|
"next.orly.dev/pkg/encoders/event/examples"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -120,7 +120,7 @@ func TestDeletionEventWithETagRejection(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
// Create a signer
|
// Create a signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ func TestSaveExistingEvent(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
// Create a signer
|
// Create a signer
|
||||||
sign := new(p256k.Signer)
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
if err := sign.Generate(); chk.E(err) {
|
if err := sign.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/envelopes"
|
"next.orly.dev/pkg/encoders/envelopes"
|
||||||
"next.orly.dev/pkg/protocol/auth"
|
"next.orly.dev/pkg/protocol/auth"
|
||||||
"next.orly.dev/pkg/utils"
|
"next.orly.dev/pkg/utils"
|
||||||
@@ -15,7 +15,7 @@ const relayURL = "wss://example.com"
|
|||||||
|
|
||||||
func TestAuth(t *testing.T) {
|
func TestAuth(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
signer := new(p256k.Signer)
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.Generate(); chk.E(err) {
|
if err = signer.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/encoders/kind"
|
"next.orly.dev/pkg/encoders/kind"
|
||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// createTestEvent creates a realistic test event with proper signing
|
// createTestEvent creates a realistic test event with proper signing
|
||||||
func createTestEvent() *E {
|
func createTestEvent() *E {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ func createTestEvent() *E {
|
|||||||
|
|
||||||
// createLargeTestEvent creates a larger event with more tags and content
|
// createLargeTestEvent creates a larger event with more tags and content
|
||||||
func createLargeTestEvent() *E {
|
func createLargeTestEvent() *E {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/errorf"
|
"lol.mleku.dev/errorf"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
"next.orly.dev/pkg/interfaces/signer"
|
||||||
"next.orly.dev/pkg/utils"
|
"next.orly.dev/pkg/utils"
|
||||||
)
|
)
|
||||||
@@ -26,7 +26,7 @@ func (ev *E) Sign(keys signer.I) (err error) {
|
|||||||
// Verify an event is signed by the pubkey it contains. Uses
|
// Verify an event is signed by the pubkey it contains. Uses
|
||||||
// github.com/bitcoin-core/secp256k1 if available for faster verification.
|
// github.com/bitcoin-core/secp256k1 if available for faster verification.
|
||||||
func (ev *E) Verify() (valid bool, err error) {
|
func (ev *E) Verify() (valid bool, err error) {
|
||||||
keys := p256k.Signer{}
|
keys := p256k1signer.NewP256K1Signer()
|
||||||
if err = keys.InitPub(ev.Pubkey); chk.E(err) {
|
if err = keys.InitPub(ev.Pubkey); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/crypto/sha256"
|
"next.orly.dev/pkg/crypto/sha256"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -29,7 +29,7 @@ func createTestFilter() *F {
|
|||||||
|
|
||||||
// Add some authors
|
// Add some authors
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func createComplexFilter() *F {
|
|||||||
|
|
||||||
// Add many authors
|
// Add many authors
|
||||||
for i := 0; i < 15; i++ {
|
for i := 0; i < 15; i++ {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ func createComplexFilter() *F {
|
|||||||
|
|
||||||
// createTestEvent creates a test event for matching
|
// createTestEvent creates a test event for matching
|
||||||
func createTestEvent() *event.E {
|
func createTestEvent() *event.E {
|
||||||
signer := &p256k.Signer{}
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); err != nil {
|
if err := signer.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Helper function to create test event for benchmarks (reuses signer)
|
// Helper function to create test event for benchmarks (reuses signer)
|
||||||
func createTestEventBench(b *testing.B, signer *p256k.Signer, content string, kind uint16) *event.E {
|
func createTestEventBench(b *testing.B, signer *p256k1signer.P256K1Signer, content string, kind uint16) *event.E {
|
||||||
ev := event.New()
|
ev := event.New()
|
||||||
ev.CreatedAt = time.Now().Unix()
|
ev.CreatedAt = time.Now().Unix()
|
||||||
ev.Kind = kind
|
ev.Kind = kind
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/encoders/kind"
|
"next.orly.dev/pkg/encoders/kind"
|
||||||
@@ -23,13 +23,13 @@ func TestPolicyIntegration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate test keys
|
// Generate test keys
|
||||||
allowedSigner := &p256k.Signer{}
|
allowedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := allowedSigner.Generate(); chk.E(err) {
|
if err := allowedSigner.Generate(); chk.E(err) {
|
||||||
t.Fatalf("Failed to generate allowed signer: %v", err)
|
t.Fatalf("Failed to generate allowed signer: %v", err)
|
||||||
}
|
}
|
||||||
allowedPubkeyHex := hex.Enc(allowedSigner.Pub())
|
allowedPubkeyHex := hex.Enc(allowedSigner.Pub())
|
||||||
|
|
||||||
unauthorizedSigner := &p256k.Signer{}
|
unauthorizedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := unauthorizedSigner.Generate(); chk.E(err) {
|
if err := unauthorizedSigner.Generate(); chk.E(err) {
|
||||||
t.Fatalf("Failed to generate unauthorized signer: %v", err)
|
t.Fatalf("Failed to generate unauthorized signer: %v", err)
|
||||||
}
|
}
|
||||||
@@ -367,13 +367,13 @@ func TestPolicyWithRelay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate keys
|
// Generate keys
|
||||||
allowedSigner := &p256k.Signer{}
|
allowedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := allowedSigner.Generate(); chk.E(err) {
|
if err := allowedSigner.Generate(); chk.E(err) {
|
||||||
t.Fatalf("Failed to generate allowed signer: %v", err)
|
t.Fatalf("Failed to generate allowed signer: %v", err)
|
||||||
}
|
}
|
||||||
allowedPubkeyHex := hex.Enc(allowedSigner.Pub())
|
allowedPubkeyHex := hex.Enc(allowedSigner.Pub())
|
||||||
|
|
||||||
unauthorizedSigner := &p256k.Signer{}
|
unauthorizedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := unauthorizedSigner.Generate(); chk.E(err) {
|
if err := unauthorizedSigner.Generate(); chk.E(err) {
|
||||||
t.Fatalf("Failed to generate unauthorized signer: %v", err)
|
t.Fatalf("Failed to generate unauthorized signer: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
@@ -22,8 +22,8 @@ func int64Ptr(i int64) *int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to generate a keypair for testing
|
// Helper function to generate a keypair for testing
|
||||||
func generateTestKeypair(t *testing.T) (signer *p256k.Signer, pubkey []byte) {
|
func generateTestKeypair(t *testing.T) (signer *p256k1signer.P256K1Signer, pubkey []byte) {
|
||||||
signer = &p256k.Signer{}
|
signer = p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); chk.E(err) {
|
if err := signer.Generate(); chk.E(err) {
|
||||||
t.Fatalf("Failed to generate test keypair: %v", err)
|
t.Fatalf("Failed to generate test keypair: %v", err)
|
||||||
}
|
}
|
||||||
@@ -32,8 +32,8 @@ func generateTestKeypair(t *testing.T) (signer *p256k.Signer, pubkey []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to generate a keypair for benchmarks
|
// Helper function to generate a keypair for benchmarks
|
||||||
func generateTestKeypairB(b *testing.B) (signer *p256k.Signer, pubkey []byte) {
|
func generateTestKeypairB(b *testing.B) (signer *p256k1signer.P256K1Signer, pubkey []byte) {
|
||||||
signer = &p256k.Signer{}
|
signer = p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); chk.E(err) {
|
if err := signer.Generate(); chk.E(err) {
|
||||||
b.Fatalf("Failed to generate test keypair: %v", err)
|
b.Fatalf("Failed to generate test keypair: %v", err)
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func generateTestKeypairB(b *testing.B) (signer *p256k.Signer, pubkey []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to create a real test event with proper signing
|
// Helper function to create a real test event with proper signing
|
||||||
func createTestEvent(t *testing.T, signer *p256k.Signer, content string, kind uint16) *event.E {
|
func createTestEvent(t *testing.T, signer *p256k1signer.P256K1Signer, content string, kind uint16) *event.E {
|
||||||
ev := event.New()
|
ev := event.New()
|
||||||
ev.CreatedAt = time.Now().Unix()
|
ev.CreatedAt = time.Now().Unix()
|
||||||
ev.Kind = kind
|
ev.Kind = kind
|
||||||
@@ -58,7 +58,7 @@ func createTestEvent(t *testing.T, signer *p256k.Signer, content string, kind ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to create a test event with a specific pubkey (for unauthorized tests)
|
// Helper function to create a test event with a specific pubkey (for unauthorized tests)
|
||||||
func createTestEventWithPubkey(t *testing.T, signer *p256k.Signer, content string, kind uint16) *event.E {
|
func createTestEventWithPubkey(t *testing.T, signer *p256k1signer.P256K1Signer, content string, kind uint16) *event.E {
|
||||||
ev := event.New()
|
ev := event.New()
|
||||||
ev.CreatedAt = time.Now().Unix()
|
ev.CreatedAt = time.Now().Unix()
|
||||||
ev.Kind = kind
|
ev.Kind = kind
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"lol.mleku.dev/log"
|
"lol.mleku.dev/log"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateUnsigned(t *testing.T) {
|
func TestCreateUnsigned(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
signer := new(p256k.Signer)
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err = signer.Generate(); chk.E(err) {
|
if err = signer.Generate(); chk.E(err) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/ec/secp256k1"
|
"next.orly.dev/pkg/crypto/ec/secp256k1"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/bech32encoding"
|
"next.orly.dev/pkg/encoders/bech32encoding"
|
||||||
"next.orly.dev/pkg/protocol/directory"
|
"next.orly.dev/pkg/protocol/directory"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Helper to create a test keypair using p256k.Signer
|
// Helper to create a test keypair using p256k1signer.P256K1Signer
|
||||||
func createTestKeypair(t *testing.T) (*p256k.Signer, []byte) {
|
func createTestKeypair(t *testing.T) (*p256k1signer.P256K1Signer, []byte) {
|
||||||
signer := new(p256k.Signer)
|
signer := p256k1signer.NewP256K1Signer()
|
||||||
if err := signer.Generate(); chk.E(err) {
|
if err := signer.Generate(); chk.E(err) {
|
||||||
t.Fatalf("failed to generate keypair: %v", err)
|
t.Fatalf("failed to generate keypair: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"next.orly.dev/pkg/crypto/encryption"
|
"next.orly.dev/pkg/crypto/encryption"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/encoders/tag"
|
"next.orly.dev/pkg/encoders/tag"
|
||||||
@@ -101,7 +101,7 @@ func TestNWCEventCreation(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientKey := &p256k.Signer{}
|
clientKey := p256k1signer.NewP256K1Signer()
|
||||||
if err := clientKey.InitSec(secretBytes); err != nil {
|
if err := clientKey.InitSec(secretBytes); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/encryption"
|
"next.orly.dev/pkg/crypto/encryption"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -40,7 +40,7 @@ func NewMockWalletService(
|
|||||||
relay string, initialBalance int64,
|
relay string, initialBalance int64,
|
||||||
) (service *MockWalletService, err error) {
|
) (service *MockWalletService, err error) {
|
||||||
// Generate wallet keypair
|
// Generate wallet keypair
|
||||||
walletKey := &p256k.Signer{}
|
walletKey := p256k1signer.NewP256K1Signer()
|
||||||
if err = walletKey.Generate(); chk.E(err) {
|
if err = walletKey.Generate(); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/encryption"
|
"next.orly.dev/pkg/crypto/encryption"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
"next.orly.dev/pkg/interfaces/signer"
|
"next.orly.dev/pkg/interfaces/signer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ func ParseConnectionURI(nwcUri string) (parts *ConnectionParams, err error) {
|
|||||||
err = errors.New("incorrect scheme")
|
err = errors.New("incorrect scheme")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if parts.walletPublicKey, err = p256k.HexToBin(p.Host); chk.E(err) {
|
if parts.walletPublicKey, err = hex.Dec(p.Host); chk.E(err) {
|
||||||
err = errors.New("invalid public key")
|
err = errors.New("invalid public key")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -62,11 +63,11 @@ func ParseConnectionURI(nwcUri string) (parts *ConnectionParams, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var secretBytes []byte
|
var secretBytes []byte
|
||||||
if secretBytes, err = p256k.HexToBin(secret); chk.E(err) {
|
if secretBytes, err = hex.Dec(secret); chk.E(err) {
|
||||||
err = errors.New("invalid secret")
|
err = errors.New("invalid secret")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
clientKey := &p256k.Signer{}
|
clientKey := p256k1signer.NewP256K1Signer()
|
||||||
if err = clientKey.InitSec(secretBytes); chk.E(err) {
|
if err = clientKey.InitSec(secretBytes); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -36,7 +36,7 @@ func TestPublish(t *testing.T) {
|
|||||||
Tags: tag.NewS(tag.NewFromAny("foo", "bar")),
|
Tags: tag.NewS(tag.NewFromAny("foo", "bar")),
|
||||||
Pubkey: pub,
|
Pubkey: pub,
|
||||||
}
|
}
|
||||||
sign := &p256k.Signer{}
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
var err error
|
var err error
|
||||||
if err = sign.InitSec(priv); chk.E(err) {
|
if err = sign.InitSec(priv); chk.E(err) {
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ var anyOriginHandshake = func(conf *websocket.Config, r *http.Request) error {
|
|||||||
|
|
||||||
func makeKeyPair(t *testing.T) (sec, pub []byte) {
|
func makeKeyPair(t *testing.T) (sec, pub []byte) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
sign := &p256k.Signer{}
|
sign := p256k1signer.NewP256K1Signer()
|
||||||
var err error
|
var err error
|
||||||
if err = sign.Generate(); chk.E(err) {
|
if err = sign.Generate(); chk.E(err) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v0.23.1
|
v0.23.2
|
||||||
@@ -36,6 +36,19 @@ func NewClient(url string) (c *Client, err error) {
|
|||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up ping/pong handling to keep connection alive
|
||||||
|
pongWait := 60 * time.Second
|
||||||
|
conn.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
// Set pong handler to extend deadline when pongs are received
|
||||||
|
// Note: Relay sends pings, gorilla/websocket auto-responds with pongs
|
||||||
|
// The relay typically doesn't send pongs back, so we also handle timeouts in readLoop
|
||||||
|
conn.SetPongHandler(func(string) error {
|
||||||
|
conn.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// Don't set ping handler - let gorilla/websocket auto-respond to pings
|
||||||
|
|
||||||
c = &Client{
|
c = &Client{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
url: url,
|
url: url,
|
||||||
@@ -78,16 +91,41 @@ func (c *Client) Send(msg interface{}) (err error) {
|
|||||||
// readLoop reads messages from the relay and routes them to subscriptions.
|
// readLoop reads messages from the relay and routes them to subscriptions.
|
||||||
func (c *Client) readLoop() {
|
func (c *Client) readLoop() {
|
||||||
defer c.conn.Close()
|
defer c.conn.Close()
|
||||||
|
pongWait := 60 * time.Second
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
// Don't set deadline here - let pong handler manage it
|
||||||
|
// SetReadDeadline is called initially in NewClient and extended by pong handler
|
||||||
_, msg, err := c.conn.ReadMessage()
|
_, msg, err := c.conn.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Check if context is done
|
||||||
|
select {
|
||||||
|
case <-c.ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
// Check if it's a timeout - connection might still be alive
|
||||||
|
if netErr, ok := err.(interface{ Timeout() bool }); ok && netErr.Timeout() {
|
||||||
|
// Pong handler should have extended deadline, but if we timeout,
|
||||||
|
// reset it and continue - connection might still be alive
|
||||||
|
// This can happen during idle periods when no messages are received
|
||||||
|
c.conn.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
// Continue reading - connection should still be alive if pings/pongs are working
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// For other errors, check if it's a close error
|
||||||
|
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// For other errors, return (connection is likely dead)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Extend read deadline on successful read
|
||||||
|
c.conn.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
var raw []interface{}
|
var raw []interface{}
|
||||||
if err = json.Unmarshal(msg, &raw); err != nil {
|
if err = json.Unmarshal(msg, &raw); err != nil {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/bech32encoding"
|
"next.orly.dev/pkg/encoders/bech32encoding"
|
||||||
"next.orly.dev/pkg/encoders/event"
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
|
|
||||||
// KeyPair represents a test keypair.
|
// KeyPair represents a test keypair.
|
||||||
type KeyPair struct {
|
type KeyPair struct {
|
||||||
Secret *p256k.Signer
|
Secret *p256k1signer.P256K1Signer
|
||||||
Pubkey []byte
|
Pubkey []byte
|
||||||
Nsec string
|
Nsec string
|
||||||
Npub string
|
Npub string
|
||||||
@@ -25,7 +25,7 @@ type KeyPair struct {
|
|||||||
// GenerateKeyPair generates a new keypair for testing.
|
// GenerateKeyPair generates a new keypair for testing.
|
||||||
func GenerateKeyPair() (kp *KeyPair, err error) {
|
func GenerateKeyPair() (kp *KeyPair, err error) {
|
||||||
kp = &KeyPair{}
|
kp = &KeyPair{}
|
||||||
kp.Secret = &p256k.Signer{}
|
kp.Secret = p256k1signer.NewP256K1Signer()
|
||||||
if err = kp.Secret.Generate(); chk.E(err) {
|
if err = kp.Secret.Generate(); chk.E(err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ func GenerateKeyPair() (kp *KeyPair, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateEvent creates a signed event with the given parameters.
|
// CreateEvent creates a signed event with the given parameters.
|
||||||
func CreateEvent(signer *p256k.Signer, kindNum uint16, content string, tags *tag.S) (ev *event.E, err error) {
|
func CreateEvent(signer *p256k1signer.P256K1Signer, kindNum uint16, content string, tags *tag.S) (ev *event.E, err error) {
|
||||||
ev = event.New()
|
ev = event.New()
|
||||||
ev.CreatedAt = time.Now().Unix()
|
ev.CreatedAt = time.Now().Unix()
|
||||||
ev.Kind = kindNum
|
ev.Kind = kindNum
|
||||||
@@ -61,7 +61,7 @@ func CreateEvent(signer *p256k.Signer, kindNum uint16, content string, tags *tag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateEventWithTags creates an event with specific tags.
|
// CreateEventWithTags creates an event with specific tags.
|
||||||
func CreateEventWithTags(signer *p256k.Signer, kindNum uint16, content string, tagPairs [][]string) (ev *event.E, err error) {
|
func CreateEventWithTags(signer *p256k1signer.P256K1Signer, kindNum uint16, content string, tagPairs [][]string) (ev *event.E, err error) {
|
||||||
tags := tag.NewS()
|
tags := tag.NewS()
|
||||||
for _, pair := range tagPairs {
|
for _, pair := range tagPairs {
|
||||||
if len(pair) >= 2 {
|
if len(pair) >= 2 {
|
||||||
@@ -78,17 +78,17 @@ func CreateEventWithTags(signer *p256k.Signer, kindNum uint16, content string, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateReplaceableEvent creates a replaceable event (kind 0-3, 10000-19999).
|
// CreateReplaceableEvent creates a replaceable event (kind 0-3, 10000-19999).
|
||||||
func CreateReplaceableEvent(signer *p256k.Signer, kindNum uint16, content string) (ev *event.E, err error) {
|
func CreateReplaceableEvent(signer *p256k1signer.P256K1Signer, kindNum uint16, content string) (ev *event.E, err error) {
|
||||||
return CreateEvent(signer, kindNum, content, nil)
|
return CreateEvent(signer, kindNum, content, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateEphemeralEvent creates an ephemeral event (kind 20000-29999).
|
// CreateEphemeralEvent creates an ephemeral event (kind 20000-29999).
|
||||||
func CreateEphemeralEvent(signer *p256k.Signer, kindNum uint16, content string) (ev *event.E, err error) {
|
func CreateEphemeralEvent(signer *p256k1signer.P256K1Signer, kindNum uint16, content string) (ev *event.E, err error) {
|
||||||
return CreateEvent(signer, kindNum, content, nil)
|
return CreateEvent(signer, kindNum, content, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateDeleteEvent creates a deletion event (kind 5).
|
// CreateDeleteEvent creates a deletion event (kind 5).
|
||||||
func CreateDeleteEvent(signer *p256k.Signer, eventIDs [][]byte, reason string) (ev *event.E, err error) {
|
func CreateDeleteEvent(signer *p256k1signer.P256K1Signer, eventIDs [][]byte, reason string) (ev *event.E, err error) {
|
||||||
tags := tag.NewS()
|
tags := tag.NewS()
|
||||||
for _, id := range eventIDs {
|
for _, id := range eventIDs {
|
||||||
// e tags must contain hex-encoded event IDs
|
// e tags must contain hex-encoded event IDs
|
||||||
@@ -101,7 +101,7 @@ func CreateDeleteEvent(signer *p256k.Signer, eventIDs [][]byte, reason string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateParameterizedReplaceableEvent creates a parameterized replaceable event (kind 30000-39999).
|
// CreateParameterizedReplaceableEvent creates a parameterized replaceable event (kind 30000-39999).
|
||||||
func CreateParameterizedReplaceableEvent(signer *p256k.Signer, kindNum uint16, content string, dTag string) (ev *event.E, err error) {
|
func CreateParameterizedReplaceableEvent(signer *p256k1signer.P256K1Signer, kindNum uint16, content string, dTag string) (ev *event.E, err error) {
|
||||||
tags := tag.NewS()
|
tags := tag.NewS()
|
||||||
tags.Append(tag.NewFromBytesSlice([]byte("d"), []byte(dTag)))
|
tags.Append(tag.NewFromBytesSlice([]byte("d"), []byte(dTag)))
|
||||||
return CreateEvent(signer, kindNum, content, tags)
|
return CreateEvent(signer, kindNum, content, tags)
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"next.orly.dev/pkg/crypto/p256k"
|
p256k1signer "p256k1.mleku.dev/signer"
|
||||||
"next.orly.dev/pkg/encoders/hex"
|
"next.orly.dev/pkg/encoders/hex"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Generate allowed signer
|
// Generate allowed signer
|
||||||
allowedSigner := &p256k.Signer{}
|
allowedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := allowedSigner.Generate(); err != nil {
|
if err := allowedSigner.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ func main() {
|
|||||||
allowedSecHex := hex.Enc(allowedSigner.Sec())
|
allowedSecHex := hex.Enc(allowedSigner.Sec())
|
||||||
|
|
||||||
// Generate unauthorized signer
|
// Generate unauthorized signer
|
||||||
unauthorizedSigner := &p256k.Signer{}
|
unauthorizedSigner := p256k1signer.NewP256K1Signer()
|
||||||
if err := unauthorizedSigner.Generate(); err != nil {
|
if err := unauthorizedSigner.Generate(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
89
scripts/test-workflow-act.sh
Executable file
89
scripts/test-workflow-act.sh
Executable file
@@ -0,0 +1,89 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Run GitHub Actions workflow locally using act
|
||||||
|
# Usage: ./scripts/test-workflow-local.sh [job-name]
|
||||||
|
# job-name: optional, defaults to 'build'. Can be 'build' or 'release'
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
WORKFLOW_FILE="${SCRIPT_DIR}/../.github/workflows/go.yml"
|
||||||
|
JOB_NAME="${1:-build}"
|
||||||
|
|
||||||
|
# Check if act is installed
|
||||||
|
if ! command -v act >/dev/null 2>&1; then
|
||||||
|
echo "Error: 'act' is not installed"
|
||||||
|
echo "Install it with:"
|
||||||
|
echo " curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash"
|
||||||
|
echo " # or on macOS: brew install act"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Running GitHub Actions workflow locally ==="
|
||||||
|
echo "Workflow: .github/workflows/go.yml"
|
||||||
|
echo "Job: $JOB_NAME"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
case "$JOB_NAME" in
|
||||||
|
build)
|
||||||
|
echo "Running build job..."
|
||||||
|
act push --workflows "$WORKFLOW_FILE" --job build
|
||||||
|
;;
|
||||||
|
release)
|
||||||
|
echo "Running release job (simulating tag push)..."
|
||||||
|
# Simulate a tag push event with a valid tag format
|
||||||
|
# The workflow requires build to run first and succeed
|
||||||
|
echo "Step 1: Running build job (required dependency)..."
|
||||||
|
if ! act push --workflows "$WORKFLOW_FILE" --job build; then
|
||||||
|
echo "Error: Build job failed. Release job cannot proceed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Step 2: Running release job..."
|
||||||
|
echo "Note: GitHub release creation may fail locally (no valid token), but binary building will be tested"
|
||||||
|
# Use a tag that matches the workflow pattern: v[0-9]+.[0-9]+.[0-9]+
|
||||||
|
# Provide a dummy GITHUB_TOKEN to prevent immediate failure
|
||||||
|
# The release won't actually be created, but the workflow will test binary building
|
||||||
|
# Temporarily disable exit on error to allow release step to fail gracefully
|
||||||
|
set +e
|
||||||
|
GITHUB_REF=refs/tags/v1.0.0 \
|
||||||
|
GITHUB_TOKEN=dummy_token_for_local_testing \
|
||||||
|
act push \
|
||||||
|
--workflows "$WORKFLOW_FILE" \
|
||||||
|
--job release \
|
||||||
|
--secret GITHUB_TOKEN=dummy_token_for_local_testing \
|
||||||
|
--eventpath /dev/stdin <<EOF
|
||||||
|
{
|
||||||
|
"ref": "refs/tags/v1.0.0",
|
||||||
|
"pusher": {"name": "test"},
|
||||||
|
"repository": {
|
||||||
|
"name": "next.orly.dev",
|
||||||
|
"full_name": "test/next.orly.dev"
|
||||||
|
},
|
||||||
|
"head_commit": {
|
||||||
|
"id": "test123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
RELEASE_EXIT_CODE=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check if binary building succeeded (exit code 0) or if only release creation failed
|
||||||
|
if [ $RELEASE_EXIT_CODE -eq 0 ]; then
|
||||||
|
echo "✓ Release job completed successfully (including binary building)"
|
||||||
|
else
|
||||||
|
echo "⚠ Release job completed with errors (likely GitHub release creation failed)"
|
||||||
|
echo " This is expected in local testing. Binary building should have succeeded."
|
||||||
|
echo " Check the output above to verify 'Build Release Binaries' step succeeded."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Error: Unknown job '$JOB_NAME'"
|
||||||
|
echo "Valid jobs: build, release"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Workflow completed ==="
|
||||||
|
|
||||||
26
scripts/test-workflow-local.sh
Executable file
26
scripts/test-workflow-local.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Manual test script for .github/workflows/go.yml
|
||||||
|
# This replicates the build job steps locally
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=== Testing GitHub Actions Workflow Locally ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check Go version
|
||||||
|
echo "Checking Go version..."
|
||||||
|
go version
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Build without cgo
|
||||||
|
echo "Building with cgo disabled..."
|
||||||
|
CGO_ENABLED=0 go build -v ./...
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test without cgo
|
||||||
|
echo "Testing with cgo disabled..."
|
||||||
|
CGO_ENABLED=0 go test -v $(go list ./... | xargs -n1 sh -c 'ls $0/*_test.go 1>/dev/null 2>&1 && echo $0' | grep .)
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Build job completed successfully ==="
|
||||||
|
|
||||||
Reference in New Issue
Block a user