func SignMessage(message string, key *bitecdsa.PrivateKey, compressed bool, rand io.Reader) (string, error) { digest := SignatureDigest(message) r, s, err := bitecdsa.Sign(rand, key, digest) if err != nil { return "", err } data := make([]byte, 65) rbytes := r.Bytes() copy(data[33-len(rbytes):33], rbytes) sbytes := s.Bytes() copy(data[65-len(sbytes):65], sbytes) for recid := 0; recid < 4; recid++ { data[0] = byte(27 + recid) qx, qy, err := RecoverPubKeyFromSignature(r, s, digest, bitelliptic.S256(), uint(recid)) if err != nil { return "", err } if 0 == qx.Cmp(key.PublicKey.X) && 0 == qy.Cmp(key.PublicKey.Y) { if compressed { data[0] += 4 } return base64.StdEncoding.EncodeToString(data), nil } } return "", ErrCouldNotSign }
// Verifies that a message was signed by the specified address. func VerifySignature(message, address string, signature []byte) error { if len(signature) != 65 { return fmt.Errorf("Bad signature length %v (should be 65 bytes)", len(signature)) } networkId, _, err := DecodeBitcoinAddress(address) if err != nil { return err } sigr := new(big.Int).SetBytes(signature[1:33]) sigs := new(big.Int).SetBytes(signature[33:65]) recid := uint(signature[0] - 27) compressed := false if recid > 3 { recid -= 4 compressed = true } digest := SignatureDigest(message) qx, qy, err := RecoverPubKeyFromSignature(sigr, sigs, digest, bitelliptic.S256(), recid&3) if err != nil { return fmt.Errorf("Error recovering public key from signature: %v", err) } if !bitecdsa.Verify(&bitecdsa.PublicKey{bitelliptic.S256(), qx, qy}, digest, sigr, sigs) { return fmt.Errorf("Invalid signature") } pubkey, err := EncodePublicKey(qx, qy, compressed) if err != nil { return fmt.Errorf("Error encoding public key: %v", err) } recoveredAddress := PublicKeyToBitcoinAddress(networkId, pubkey) if address != recoveredAddress { return fmt.Errorf("Signature doesn't match document %#v", message) } return nil }
func TestSignAndVerify(t *testing.T) { testSignAndVerify(t, bitelliptic.S256(), "S256") if testing.Short() { return } testSignAndVerify(t, bitelliptic.S160(), "S160") testSignAndVerify(t, bitelliptic.S192(), "S192") testSignAndVerify(t, bitelliptic.S224(), "S224") }
func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, bitelliptic.S256(), "S256") if testing.Short() { return } testKeyGeneration(t, bitelliptic.S160(), "S160") testKeyGeneration(t, bitelliptic.S192(), "S192") testKeyGeneration(t, bitelliptic.S224(), "S224") }
func CombinePublicKeys(one, two string) (*big.Int, *big.Int) { a, b := PublicKeyToPointCoordinates(one) c, d := PublicKeyToPointCoordinates(two) e, f := bitelliptic.S256().Add(a, b, c, d) log.Printf("04%X%X", Big2Hex(e), Big2Hex(f)) return e, f }
func CheckSolution(pubKey, solution, pattern string, netByte byte) (string, string) { d := big.NewInt(0) d.SetString(solution, 16) private, err := bitecdsa.GenerateFromPrivateKey(d, bitelliptic.S256()) if err != nil { log.Printf("vanitymath err - %s", err) return "", err.Error() } a, b := PublicKeyToPointCoordinates(pubKey) x, y := bitelliptic.S256().Add(a, b, private.PublicKey.X, private.PublicKey.Y) ba := NewFromPublicKeyString(netByte, PointCoordinatesToPublicKey(x, y)) address := string(ba.Base) for i := 0; i < len(pattern); i++ { if address[i] != pattern[i] { return "", "Wrong pattern" } } return address, "" }
func NewAddressFromPrivateKeyOtherNets(netByte byte, privateKey []byte) (*BitAddress, error) { curve := bitelliptic.S256() priv, err := bitecdsa.GenerateFromPrivateKey(Hex2Big(privateKey), curve) if err != nil { return nil, err } ba := new(BitAddress) ba.PrivateKey = Big2Hex(priv.D) ba.Encrypted = false ba.PublicKey = append(append([]byte{netByte}, Big2Hex(priv.PublicKey.X)...), Big2Hex(priv.PublicKey.Y)...) ba.Hash160 = SHARipemd(ba.PublicKey) ba.Hash = append(append([]byte{0x00}, ba.Hash160...), DoubleSHA(append([]byte{0x00}, ba.Hash160...))[0:4]...) ba.Base = Hex2Base58(ba.Hash) return ba, nil }
func NewRandomAddress() (*BitAddress, error) { curve := bitelliptic.S256() priv, err := bitecdsa.GenerateKey(curve, rand.Reader) if err != nil { return nil, err } ba := new(BitAddress) ba.PrivateKey = Big2Hex(priv.D) ba.Encrypted = false ba.PublicKey = append(append([]byte{0x04}, Big2Hex(priv.PublicKey.X)...), Big2Hex(priv.PublicKey.Y)...) ba.Hash160 = SHARipemd(ba.PublicKey) ba.Hash = append(append([]byte{0x00}, ba.Hash160...), DoubleSHA(append([]byte{0x00}, ba.Hash160...))[0:4]...) ba.Base = Hex2Base58(ba.Hash) return ba, nil }
func FromPrivateKeyRaw(privKey []byte, compressed bool, addrVersion byte) (*KeyPair, error) { curve := bitelliptic.S256() k := KeyPair{ privKey: privKey, compressed: compressed, addrVersion: addrVersion, } if ecdsakey, err := bitecdsa.GenerateFromPrivateKey(new(big.Int).SetBytes(k.privKey), curve); err != nil { return nil, err } else { k.ecdsakey = ecdsakey } if pubkey, err := EncodePublicKey(k.ecdsakey.X, k.ecdsakey.Y, k.compressed); err != nil { panic(err) // Shouldn't happen } else { k.address = PublicKeyToBitcoinAddress(addrVersion, pubkey) } return &k, nil }
func Test_DecodePrivateKeyWif(t *testing.T) { type positive struct { privKey string compressed bool address string } for _, c := range []positive{ {"5KJvsngHeMpm884wtkJNzQGaCErckhHJBGFsvd3VyK5qMZXj3hS", false, "1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T"}, {"L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu", true, "1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8"}, } { key, compressed, err := DecodePrivateKeyWIF(c.privKey) if err != nil { t.Errorf("Unexpected error decoding private key: %v", err) return } if compressed != c.compressed { t.Errorf("Compressed flag is %v but should be %v", compressed, c.compressed) return } curve := bitelliptic.S256() x, y := curve.ScalarBaseMult(key) pubkey, err := EncodePublicKey(x, y, compressed) if err != nil { t.Errorf("Unexpected error encoding public key: %v", err) } address := PublicKeyToBitcoinAddress(0, pubkey) if address != c.address { t.Errorf("Test case failed: %#v", c) } } }
func TestVectors(t *testing.T) { sha := sha1.New() for i, test := range testVectors { pub := PublicKey{ BitCurve: bitelliptic.S256(), X: fromHex(test.Qx), Y: fromHex(test.Qy), } msg, _ := hex.DecodeString(test.msg) sha.Reset() sha.Write(msg) hashed := sha.Sum() r := fromHex(test.r) s := fromHex(test.s) if Verify(&pub, hashed, r, s) != test.ok { t.Errorf("%d: bad result", i) } if testing.Short() { break } } }
func CombinePrivateKeys(one, two string) *big.Int { a := big.NewInt(0) b := big.NewInt(0) a.SetString(one, 16) b.SetString(two, 16) one1 := big.NewInt(1) tmp := a.Add(a, b) tmp = tmp.Sub(tmp, one1) //mod,_:=new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16) //mod:=new(big.Int).Sub(bitelliptic.S256().P, one1) mod := bitelliptic.S256().N tmp = tmp.Mod(tmp, mod) answer := tmp.Add(tmp, one1) //answer:=tmp //answer:=a.Mod(a.Add(a, b), bitelliptic.S256().P) log.Printf("Sum 1 - %X", Big2Hex(answer)) return answer }
func main() { fmt.Println("Hello world!") file, err := os.Open("address.txt") if err != nil { fmt.Println("Can't find address.txt file. Terminating.") return } reader := bufio.NewReader(file) part, _, err := reader.ReadLine() if err != nil { fmt.Println("Problems reading address.txt file. Terminating.") return } Address = string(part) fmt.Println("Your address is - ", Address) fmt.Println("Fetching work (vanitypooltest)...") response, err := http.Get("https://vanitypooltest.appspot.com/getWork") if err != nil { fmt.Println("Problems fetching work. Terminating.") return } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Problems reading fetched work. Terminating.") return } workString := string(body) fmt.Println("Fetched work:") fmt.Println(workString) if len(workString) == 0 { fmt.Println("No work. Terminating.") return } tasks := mymath.SplitStrings(workString, "\n") work := make([]Work, len(tasks)-1) for i := 0; i < len(tasks)-1; i++ { task := mymath.SplitStrings(tasks[i], ";")[0] parts := mymath.SplitStrings(task, ":") //fmt.Println(parts) work[i].PublicKey = parts[0] work[i].Pattern = parts[1] work[i].NetByte = byte(mymath.Str2Int64(parts[2])) work[i].Reward = mymath.Str2Float(parts[3]) work[i].X, work[i].Y = mymath.PublicKeyToPointCoordinates(work[i].PublicKey) } //fmt.Println(work) fmt.Println("") fmt.Println("Starting the work!") curve := bitelliptic.S256() for count := 0; len(work) > 0; count++ { if count%100 == 99 { fmt.Println("Checked 100 keys...") } key, err := bitecdsa.GenerateKey(curve, rand.Reader) if err != nil { fmt.Println("Error encountered while generating keys:") fmt.Println(err.Error()) return } for i := 0; i < len(work); i++ { x, y := curve.Add(work[i].X, work[i].Y, key.X, key.Y) address := string(mymath.NewFromPublicKey(work[i].NetByte, append(append([]byte{0x04}, mymath.Big2HexPadded(x, 32)...), mymath.Big2HexPadded(y, 32)...)).Base) ok := true for j := 0; j < len(work[i].Pattern); j++ { if work[i].Pattern[j] != address[j] { ok = false } } if ok == true { fmt.Println("Solved a work!") fmt.Println(tasks[i]) fmt.Printf("Solution - %X\n", mymath.Big2Hex(key.D)) fmt.Println("Attempting to hand in work...") postAddress := "https://vanitypooltest.appspot.com/solveWork?key=" + work[i].PublicKey + ":" + work[i].Pattern + "&privateKey=" + mymath.Hex2Str(mymath.Big2Hex(key.D)) + "&bitcoinAddress=" + Address response, err = http.Get(postAddress) if err != nil { fmt.Println("Problems fetching work. Terminating.") return } defer response.Body.Close() body, err = ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Problems reading fetched work. Terminating.") return } fmt.Println("Server response:", string(body)) if string(body) == "OK!" { fmt.Println("Work accepted, yay!") work = append(work[0:i], work[i+1:]...) } else { fmt.Println("Work did not get accepted...") } } } } }