Skip to content

Instantly share code, notes, and snippets.

@koteitan
Last active August 9, 2025 02:03
Show Gist options
  • Select an option

  • Save koteitan/164c104b95171e4fe2d47893e4f86a99 to your computer and use it in GitHub Desktop.

Select an option

Save koteitan/164c104b95171e4fe2d47893e4f86a99 to your computer and use it in GitHub Desktop.
find twin of nostr nsec
#!/usr/bin/env node
import { nip19, getPublicKey } from 'nostr-tools'
// secp256k1 curve order
const n = 115792089237316195423570985008687907852837564279074904382605163141518161494337n
// Get nsec from command line argument
const input_nsec = process.argv[2]
// Check arguments
if (!input_nsec) {
console.log('Usage: node find-twin.js <nsec>')
console.log('Example: node find-twin.js nsec1...')
process.exit(1)
}
try {
// Decode nsec to get private key
const decoded = nip19.decode(input_nsec)
// Error if not nsec format
if (decoded.type !== 'nsec') {
console.error('Error: Please input nsec format private key')
process.exit(1)
}
// Convert Uint8Array to hex string
const sk1_hex = Array.from(decoded.data)
.map(b => b.toString(16).padStart(2, '0'))
.join('')
// Convert to BigInt
const sk1 = BigInt('0x' + sk1_hex)
// Calculate another private key
const sk2 = n - sk1
// Convert sk2 to hex
const sk2_hex = sk2.toString(16).padStart(64, '0')
// Encode sk2 to nsec format
const pair_nsec = nip19.nsecEncode(Buffer.from(sk2_hex, 'hex'))
// Generate both public keys for verification
const pubkey1 = getPublicKey(sk1_hex)
const pubkey2 = getPublicKey(sk2_hex)
const npub1 = nip19.npubEncode(pubkey1)
const npub2 = nip19.npubEncode(pubkey2)
// Display results
console.log(`nsec1: ${input_nsec}`)
console.log(`nsec2: ${pair_nsec}`)
console.log(`npub1: ${npub1}`)
console.log(`npub2: ${npub2}`)
} catch (error) {
console.error(`Error: ${error.message}`)
process.exit(1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment