// ReadKeyPair reads an ECDSA keypair a file in JSON object format. // Example JSON input: // { // "privkey": "..." // } // It also checks if a pubkey is in the keyring and, if not, appends it to the // keyring. func ReadKeyPair(filename string) (*ecdsa.PrivateKey, error) { // Load the file f, err := ioutil.ReadFile(filename) if err != nil { fError := errors.New("os.Open: Couldn't open keypair file.") return nil, fError } // Unmarshall the loaded file into a map. var keyMap = make(map[string]string) var pubkey *ecdsa.PublicKey var privkey *ecdsa.PrivateKey err = json.Unmarshal(f, &keyMap) if err != nil { jsonError := errors.New("json error: Couldn't unmarshall keypair file.") return nil, jsonError } privBytes, errDecode := hex.DecodeString(keyMap["privkey"]) if errDecode != nil { decodeError := errors.New("decode error: Couldn't decode hex for privkey.") return nil, decodeError } // PrivKeyFromBytes doesn't return an error, so this could possibly be ugly. privkeyBtcec, _ := btcec.PrivKeyFromBytes(btcec.S256(), privBytes) pubBytes, errDecode := hex.DecodeString(keyMap["pubkey"]) if errDecode != nil { decodeError := errors.New("decode error: Couldn't decode hex for privkey.") return nil, decodeError } pubkeyBtcec, errParse := btcec.ParsePubKey(pubBytes, btcec.S256()) if errParse != nil { return nil, errParse } // Assign the things to return pubkey = &ecdsa.PublicKey{pubkeyBtcec.Curve, pubkeyBtcec.X, pubkeyBtcec.Y} privkey = &ecdsa.PrivateKey{*pubkey, privkeyBtcec.D} return privkey, nil }
func main() { // Print header fmt.Printf("%64s %34s %34s\n", "Private", "Public", "Public Compressed") // Initialise big numbers with small numbers count, one := big.NewInt(0), big.NewInt(1) // Create a slice to pad our count to 32 bytes padded := make([]byte, 32) // Loop forever because we're never going to hit the end anyway for { // Increment our counter count.Add(count, one) // Copy count value's bytes to padded slice copy(padded[32-len(count.Bytes()):], count.Bytes()) // Get public key _, public := btcec.PrivKeyFromBytes(btcec.S256(), padded) // Get compressed and uncompressed addresses caddr, _ := btcutil.NewAddressPubKey(public.SerializeCompressed(), &btcnet.MainNetParams) uaddr, _ := btcutil.NewAddressPubKey(public.SerializeUncompressed(), &btcnet.MainNetParams) // Print keys fmt.Printf("%x %34s %34s\n", padded, uaddr.EncodeAddress(), caddr.EncodeAddress()) } }
func compute(count *big.Int) (keys [ResultsPerPage]Key, length int) { var padded [32]byte var i int for i = 0; i < ResultsPerPage; i++ { // Increment our counter count.Add(count, one) // Check to make sure we're not out of range if count.Cmp(total) > 0 { break } // Copy count value's bytes to padded slice copy(padded[32-len(count.Bytes()):], count.Bytes()) // Get private and public keys privKey, public := btcec.PrivKeyFromBytes(btcec.S256(), padded[:]) // Get compressed and uncompressed addresses for public key caddr, _ := btcutil.NewAddressPubKey(public.SerializeCompressed(), &btcnet.MainNetParams) uaddr, _ := btcutil.NewAddressPubKey(public.SerializeUncompressed(), &btcnet.MainNetParams) // Encode addresses wif, _ := btcutil.NewWIF(privKey, &btcnet.MainNetParams, false) keys[i].private = wif.String() keys[i].number = count.String() keys[i].compressed = caddr.EncodeAddress() keys[i].uncompressed = uaddr.EncodeAddress() } return keys, i }
// getArgs parses command line args and asserts that a private key and an // address are present and correctly formatted. func getArgs() requiredArgs { flag.Parse() if *a == "" || *k == "" || *t == "" || *v == -1 { fmt.Println("\nThis tool generates a bitcoin transaction that moves coins from an input to an output.\n" + "You must provide a key, an address, a transaction id (the hash\n" + "of a tx) and the index into the outputs of that tx that fund your\n" + "address! Use http://blockchain.info/pushtx to send the raw transaction.\n") flag.PrintDefaults() fmt.Println("") os.Exit(0) } pkBytes, err := hex.DecodeString(*k) if err != nil { log.Fatal(err) } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) addr, err := btcutil.DecodeAddress(*a, &btcnet.MainNetParams) if err != nil { log.Fatal(err) } txid, err := btcwire.NewShaHashFromStr(*t) args := requiredArgs{ txid: txid, vout: uint32(*v), toAddress: addr, privKey: privKey, } return args }
func generateKeyPair() (*btcec.PublicKey, *btcec.PrivateKey) { // Generate a private key, use the curve secpc256k1 and kill the program on // any errors priv, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { // There was an error. Log it and bail out log.Fatal(err) } return priv.PubKey(), priv }
// ReadKeyRing reads a key ring of public keys from a file in JSON object format, // and also inserts the pubkey of a keypair if it's not already present (handles // bug in URS implementation). func ReadKeyRing(filename string, kp *ecdsa.PrivateKey) (*PublicKeyRing, error) { // Load the file f, err := ioutil.ReadFile(filename) if err != nil { fError := errors.New("os.Open: Couldn't open keyring file.") return nil, fError } // Unmarshall the loaded file into a map var keyMap = make(map[string]string) err = json.Unmarshal(f, &keyMap) if err != nil { str := fmt.Sprintf("json error: Couldn't unmarshall keyring file.", err) jsonError := errors.New(str) return nil, jsonError } kr := NewPublicKeyRing(uint(len(keyMap))) // Stick the pubkeys into the keyring as long as it doesn't belong to the // keypair given. for i := 0; i < len(keyMap); i++ { pkBytes, errDecode := hex.DecodeString(keyMap[strconv.Itoa(i)]) if errDecode != nil { decodeError := errors.New("decode error: Couldn't decode hex.") return nil, decodeError } pubkey, errParse := btcec.ParsePubKey(pkBytes, btcec.S256()) if errParse != nil { return nil, errParse } ecdsaPubkey := ecdsa.PublicKey{pubkey.Curve, pubkey.X, pubkey.Y} if kp == nil || !CmpPubKey(&kp.PublicKey, &ecdsaPubkey) { kr.Add(ecdsaPubkey) } else { kr.Add(kp.PublicKey) } } // Stick the keypair in if it's missing. if kp != nil && !kr.keyInKeyRing(&kp.PublicKey) { kr.Add(kp.PublicKey) } return kr, nil }
// generateKeyPair generates and stores an ECDSA keypair to a file. func generateKeyPair(filename string) error { // Generate keypairs. aKeypair, err := ecdsa.GenerateKey(btcec.S256(), crand.Reader) if err != nil { return err } pubkeyBtcec := btcec.PublicKey{aKeypair.PublicKey.Curve, aKeypair.PublicKey.X, aKeypair.PublicKey.Y} keypairBtcec := btcec.PrivateKey{aKeypair.PublicKey, aKeypair.D} // Create a map to json marshal keypairMap := make(map[string]string) keypairMap["pubkey"] = hex.EncodeToString(pubkeyBtcec.SerializeCompressed()) keypairMap["privkey"] = hex.EncodeToString(keypairBtcec.Serialize()) // Store the address in case anyone wants to use it for BTC pkh, err := btcutil.NewAddressPubKey(pubkeyBtcec.SerializeCompressed(), &btcnet.MainNetParams) if err != nil { return err } keypairMap["address"] = pkh.EncodeAddress() b, err := json.Marshal(keypairMap) if err != nil { return err } err = ioutil.WriteFile(filename, b, 0644) if err != nil { return err } return nil }