예제 #1
0
파일: signmsg.go 프로젝트: wchh/gocoin
// this function signs either a message or a raw hash
func sign_message() {
	var hash []byte
	var signkey *btc.PrivateAddr

	signkey = address_to_key(*signaddr)
	if signkey == nil {
		println("You do not have a private key for", *signaddr)
		return
	}

	if *signhash != "" {
		hash, er := hex.DecodeString(*signhash)
		if er != nil {
			println("Incorrect content of -hash parameter")
			println(er.Error())
			return
		} else if len(hash) > 0 {
			txsig := new(btc.Signature)
			txsig.HashType = 0x01
			r, s, e := btc.EcdsaSign(signkey.Key, hash)
			if e != nil {
				println(e.Error())
				return
			}
			txsig.R.Set(r)
			txsig.S.Set(s)
			fmt.Println("PublicKey:", hex.EncodeToString(signkey.BtcAddr.Pubkey))
			fmt.Println(hex.EncodeToString(txsig.Bytes()))
			return
		}
	}

	var msg []byte
	if *message == "" {
		msg, _ = ioutil.ReadAll(os.Stdin)
	} else {
		msg = []byte(*message)
	}

	hash = make([]byte, 32)
	if litecoin {
		ltc.HashFromMessage(msg, hash)
	} else {
		btc.HashFromMessage(msg, hash)
	}

	btcsig := new(btc.Signature)
	var sb [65]byte
	sb[0] = 27
	if signkey.IsCompressed() {
		sb[0] += 4
	}

	r, s, e := btc.EcdsaSign(signkey.Key, hash)
	if e != nil {
		println(e.Error())
		return
	}
	btcsig.R.Set(r)
	btcsig.S.Set(s)

	rd := btcsig.R.Bytes()
	sd := btcsig.S.Bytes()
	copy(sb[1+32-len(rd):], rd)
	copy(sb[1+64-len(sd):], sd)

	rpk := btcsig.RecoverPublicKey(hash[:], 0)
	sa := btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
	if sa.Hash160 == signkey.BtcAddr.Hash160 {
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}

	rpk = btcsig.RecoverPublicKey(hash[:], 1)
	sa = btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
	if sa.Hash160 == signkey.BtcAddr.Hash160 {
		sb[0]++
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}
	println("Something went wrong. The message has not been signed.")
}
예제 #2
0
파일: btcversig.go 프로젝트: wchh/gocoin
func main() {
	var msg []byte

	flag.Parse()

	if *help || *addr == "" || *sign == "" {
		flag.PrintDefaults()
		return
	}

	ad, er := btc.NewAddrFromString(*addr)
	if !*litecoin && ad != nil && ad.Version == ltc.AddrVerPubkey(false) {
		*litecoin = true
	}
	if er != nil {
		println("Address:", er.Error())
		flag.PrintDefaults()
		return
	}

	nv, btcsig, er := btc.ParseMessageSignature(*sign)
	if er != nil {
		println("ParseMessageSignature:", er.Error())
		return
	}

	if *mess != "" {
		msg = []byte(*mess)
	} else if *mfil != "" {
		msg, er = ioutil.ReadFile(*mfil)
		if er != nil {
			println(er.Error())
			return
		}
	} else {
		if *verb {
			fmt.Println("Enter the message:")
		}
		msg, _ = ioutil.ReadAll(os.Stdin)
	}

	if *unix {
		if *verb {
			fmt.Println("Enforcing Unix text format")
		}
		msg = bytes.Replace(msg, []byte{'\r'}, nil, -1)
	}

	hash := make([]byte, 32)
	if *litecoin {
		ltc.HashFromMessage(msg, hash)
	} else {
		btc.HashFromMessage(msg, hash)
	}

	compressed := false
	if nv >= 31 {
		if *verb {
			fmt.Println("compressed key")
		}
		nv -= 4
		compressed = true
	}

	pub := btcsig.RecoverPublicKey(hash[:], int(nv-27))
	if pub != nil {
		pk := pub.Bytes(compressed)
		ok := btc.EcdsaVerify(pk, btcsig.Bytes(), hash)
		if ok {
			sa := btc.NewAddrFromPubkey(pk, ad.Version)
			if ad.Hash160 != sa.Hash160 {
				fmt.Println("BAD signature for", ad.String())
				if bytes.IndexByte(msg, '\r') != -1 {
					fmt.Println("You have CR chars in the message. Try to verify with -u switch.")
				}
				os.Exit(1)
			} else {
				fmt.Println("Signature OK")
			}
		} else {
			println("BAD signature")
			os.Exit(1)
		}
	} else {
		println("BAD, BAD, BAD signature")
		os.Exit(1)
	}
}