Example #1
1
// New methods using proper ecdsa keys from the stdlib
func ToECDSA(prv []byte) *ecdsa.PrivateKey {
	if len(prv) == 0 {
		return nil
	}

	priv := new(ecdsa.PrivateKey)
	priv.PublicKey.Curve = secp256k1.S256()
	priv.D = common.BigD(prv)
	priv.PublicKey.X, priv.PublicKey.Y = secp256k1.S256().ScalarBaseMult(prv)
	return priv
}
Example #2
0
// Verify the secret key's range and if a test message signed with it verifies OK
// Returns nil if averything looks OK
func VerifyKeyPair(priv []byte, publ []byte) error {
	const TestMessage = "Just some test message..."
	hash := Sha2Sum([]byte(TestMessage))

	pub_key, e := NewPublicKey(publ)
	if e != nil {
		return e
	}

	var key ecdsa.PrivateKey
	key.D = new(big.Int).SetBytes(priv)
	key.PublicKey = pub_key.PublicKey

	if key.D.Cmp(big.NewInt(0)) == 0 {
		return errors.New("pubkey value is zero")
	}

	if key.D.Cmp(secp256k1.N) != -1 {
		return errors.New("pubkey value is too big")
	}

	r, s, err := ecdsa.Sign(rand.Reader, &key, hash[:])
	if err != nil {
		return errors.New("ecdsa.Sign failed: " + err.Error())
	}

	ok := ecdsa.Verify(&key.PublicKey, hash[:], r, s)
	if !ok {
		return errors.New("ecdsa.Sign Verify")
	}
	return nil
}
Example #3
0
// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
// The OID for the named curve may be provided from another source (such as
// the PKCS8 container) - if it is provided then use this instead of the OID
// that may exist in the EC private key structure.
func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
	var privKey ecPrivateKey
	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
		return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
	}
	if privKey.Version != ecPrivKeyVersion {
		return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
	}

	var curve elliptic.Curve
	if namedCurveOID != nil {
		curve = namedCurveFromOID(*namedCurveOID)
	} else {
		curve = namedCurveFromOID(privKey.NamedCurveOID)
	}
	if curve == nil {
		return nil, errors.New("x509: unknown elliptic curve")
	}

	k := new(big.Int).SetBytes(privKey.PrivateKey)
	if k.Cmp(curve.Params().N) >= 0 {
		return nil, errors.New("x509: invalid elliptic curve private key value")
	}
	priv := new(ecdsa.PrivateKey)
	priv.Curve = curve
	priv.D = k
	priv.X, priv.Y = curve.ScalarBaseMult(privKey.PrivateKey)

	return priv, nil
}
Example #4
0
// Signs a specified transaction input
func (tx *Tx) Sign(in int, pk_script []byte, hash_type byte, pubkey, priv_key []byte) error {
	if in >= len(tx.TxIn) {
		return errors.New("tx.Sign() - input index overflow")
	}

	pub_key, er := NewPublicKey(pubkey)
	if er != nil {
		return er
	}

	// Load the key (private and public)
	var key ecdsa.PrivateKey
	key.D = new(big.Int).SetBytes(priv_key)
	key.PublicKey = pub_key.PublicKey

	//Calculate proper transaction hash
	h := tx.SignatureHash(pk_script, in, hash_type)

	// Sign
	r, s, er := EcdsaSign(&key, h)
	if er != nil {
		return er
	}
	rb := r.Bytes()
	sb := s.Bytes()

	if rb[0] >= 0x80 {
		rb = append([]byte{0x00}, rb...)
	}

	if sb[0] >= 0x80 {
		sb = append([]byte{0x00}, sb...)
	}

	// Output the signing result into a buffer, in format expected by bitcoin protocol
	busig := new(bytes.Buffer)
	busig.WriteByte(0x30)
	busig.WriteByte(byte(4 + len(rb) + len(sb)))
	busig.WriteByte(0x02)
	busig.WriteByte(byte(len(rb)))
	busig.Write(rb)
	busig.WriteByte(0x02)
	busig.WriteByte(byte(len(sb)))
	busig.Write(sb)
	busig.WriteByte(0x01) // hash type

	// Output the signature and the public key into tx.ScriptSig
	buscr := new(bytes.Buffer)
	buscr.WriteByte(byte(busig.Len()))
	buscr.Write(busig.Bytes())

	buscr.WriteByte(byte(len(pubkey)))
	buscr.Write(pubkey)

	// assign sign script ot the tx:
	tx.TxIn[in].ScriptSig = buscr.Bytes()

	return nil // no error
}
Example #5
0
func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
	if len(hash) != 32 {
		return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
	}

	sig, err = secp256k1.Sign(hash, common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8))
	return
}
Example #6
0
// PublicPEM returns the PEM-encoded public key
func PublicPEM(key *ecdsa.PrivateKey) ([]byte, error) {
	pubBytes, err := x509.MarshalPKIXPublicKey(key.Public())
	if err != nil {
		return nil, err
	}
	pubPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: pubBytes,
	})
	return pubPEM, nil
}
Example #7
0
func UnmarshalCertificate(data []byte) Certificate {
	priv := new(big.Int).SetBytes(data[:28])
	pub := UnmarshalPublicCertificate(data[28:])

	cert := new(ecdsa.PrivateKey)

	cert.D = priv
	cert.PublicKey = *pub

	return cert
}
Example #8
0
func DecodeECDSAPrivateKey(b []byte) (*ecdsa.PrivateKey, error) {
	var p []big.Int
	buf := bytes.NewBuffer(b)
	dec := gob.NewDecoder(buf)
	err := dec.Decode(&p)
	if err != nil {
		return nil, err
	}
	privateKey := new(ecdsa.PrivateKey)
	privateKey.PublicKey.Curve = btcec.S256()
	privateKey.PublicKey.X = &p[0]
	privateKey.PublicKey.Y = &p[1]
	privateKey.D = &p[2]
	return privateKey, nil
}
Example #9
0
// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
// The OID for the named curve may be provided from another source (such as
// the PKCS8 container) - if it is provided then use this instead of the OID
// that may exist in the EC private key structure.
func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
	var privKey ecPrivateKey
	if _, err := asn1.Unmarshal(der, &privKey); err != nil {
		return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
	}
	if privKey.Version != ecPrivKeyVersion {
		return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
	}

	var curve elliptic.Curve
	if namedCurveOID != nil {
		curve = namedCurveFromOID(*namedCurveOID)
	} else {
		curve = namedCurveFromOID(privKey.NamedCurveOID)
	}
	if curve == nil {
		return nil, errors.New("x509: unknown elliptic curve")
	}

	k := new(big.Int).SetBytes(privKey.PrivateKey)
	curveOrder := curve.Params().N
	if k.Cmp(curveOrder) >= 0 {
		return nil, errors.New("x509: invalid elliptic curve private key value")
	}
	priv := new(ecdsa.PrivateKey)
	priv.Curve = curve
	priv.D = k

	privateKey := make([]byte, (curveOrder.BitLen()+7)/8)

	// Some private keys have leading zero padding. This is invalid
	// according to [SEC1], but this code will ignore it.
	for len(privKey.PrivateKey) > len(privateKey) {
		if privKey.PrivateKey[0] != 0 {
			return nil, errors.New("x509: invalid private key length")
		}
		privKey.PrivateKey = privKey.PrivateKey[1:]
	}

	// Some private keys remove all leading zeros, this is also invalid
	// according to [SEC1] but since OpenSSL used to do this, we ignore
	// this too.
	copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
	priv.X, priv.Y = curve.ScalarBaseMult(privateKey)

	return priv, nil
}
Example #10
0
func newCert(key *ecdsa.PrivateKey) (cert *x509.Certificate, err error) {
	template := &x509.Certificate{
		SerialNumber: new(big.Int).SetInt64(time.Now().UnixNano()),
		Subject: pkix.Name{
			CommonName: "nutcracker",
		},
		NotBefore:          time.Now().Add(-5 * time.Minute).UTC(),
		NotAfter:           time.Now().AddDate(1, 0, 0).UTC(),
		KeyUsage:           x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		SignatureAlgorithm: x509.ECDSAWithSHA256,
	}
	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key)
	if err != nil {
		return
	}
	return x509.ParseCertificate(derBytes)
}
Example #11
0
func readPrivateKeyECDSA(m map[string]string) (PrivateKey, error) {
	p := new(ecdsa.PrivateKey)
	p.D = big.NewInt(0)
	// TODO: validate that the required flags are present
	for k, v := range m {
		switch k {
		case "privatekey":
			v1, err := fromBase64([]byte(v))
			if err != nil {
				return nil, err
			}
			p.D.SetBytes(v1)
		case "created", "publish", "activate":
			/* not used in Go (yet) */
		}
	}
	return p, nil
}
Example #12
0
func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
	ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
	ecdsaPriv := new(ecdsa.PrivateKey)
	ecdsaPriv.PublicKey = *ecdsaPub

	buf := bytes.NewBuffer(data)
	d, _, err := readMPI(buf)
	if err != nil {
		return
	}

	ecdsaPriv.D = new(big.Int).SetBytes(d)
	pk.PrivateKey = ecdsaPriv
	pk.Encrypted = false
	pk.encryptedData = nil

	return nil
}
Example #13
0
func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, os.Error) {
	p := new(ecdsa.PrivateKey)
	p.D = big.NewInt(0)
	// Need to check if we have everything
	for k, v := range kv {
		switch k {
		case "privatekey:":
			v1, err := packBase64([]byte(v))
			if err != nil {
				return nil, err
			}
			p.D.SetBytes(v1)
		case "created:", "publish:", "activate:":
			/* not used in Go (yet) */
		}
	}
	return p, nil
}
// GenerateCertificate generates an X509 Certificate from a template, given a GUN
func (ucs *UnlockedCryptoService) GenerateCertificate(gun string) (*x509.Certificate, error) {
	algorithm := ucs.PrivKey.Algorithm()
	var publicKey crypto.PublicKey
	var privateKey crypto.PrivateKey
	var err error
	switch algorithm {
	case data.RSAKey:
		var rsaPrivateKey *rsa.PrivateKey
		rsaPrivateKey, err = x509.ParsePKCS1PrivateKey(ucs.PrivKey.Private())
		privateKey = rsaPrivateKey
		publicKey = rsaPrivateKey.Public()
	case data.ECDSAKey:
		var ecdsaPrivateKey *ecdsa.PrivateKey
		ecdsaPrivateKey, err = x509.ParseECPrivateKey(ucs.PrivKey.Private())
		privateKey = ecdsaPrivateKey
		publicKey = ecdsaPrivateKey.Public()
	default:
		return nil, fmt.Errorf("only RSA or ECDSA keys are currently supported. Found: %s", algorithm)
	}
	if err != nil {
		return nil, fmt.Errorf("failed to parse root key: %s (%v)", gun, err)
	}

	template, err := trustmanager.NewCertificate(gun)
	if err != nil {
		return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err)
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, publicKey, privateKey)
	if err != nil {
		return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err)
	}

	// Encode the new certificate into PEM
	cert, err := x509.ParseCertificate(derBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err)
	}

	return cert, nil
}
Example #15
0
// GenSignature - Debugging function to sign a message
func GenSignature(w http.ResponseWriter, r *http.Request) {
	// Returns a Public / Private Key Pair
	// Uses eliptic curve cryptography

	// Generate a public / private key pair
	privatekey := new(ecdsa.PrivateKey)

	// Generate an elliptic curve using NIST P-224
	ecurve := elliptic.P224()
	privatekey, err := ecdsa.GenerateKey(ecurve, rand.Reader)

	if err != nil {
		panic(err)
	}

	// Marshal the JSON
	privkey, _ := json.Marshal(privatekey)
	publikey, _ := json.Marshal(privatekey.Public())

	// Get the public key
	var pubkey ecdsa.PublicKey
	pubkey = privatekey.PublicKey

	// Try signing a message
	message := []byte("This is a test")
	sig1, sig2, err := ecdsa.Sign(rand.Reader, privatekey, message)

	// Try verifying the signature
	result := ecdsa.Verify(&pubkey, message, sig1, sig2)
	if result != true {
		panic("Unable to verify signature")
	}

	fmt.Fprintln(w, "Marshaled Private Key:", string(privkey))
	fmt.Fprintln(w, "Marshaled Public Key:", string(publikey))
	fmt.Fprintln(w, "Curve: ", pubkey.Curve)
	fmt.Fprintf(w, "Curve: Private: %#v\nPublic: %#v\n\nSignature:\n%v\n%v\n\nVerified: %v", privatekey, pubkey, sig1, sig2, result)

}
Example #16
0
// Verify the secret key's range and al if a test message signed with it verifies OK
func verify_key(priv []byte, publ []byte) bool {
	const TestMessage = "Just some test message..."
	hash := btc.Sha2Sum([]byte(TestMessage))

	pub_key, e := btc.NewPublicKey(publ)
	if e != nil {
		println("NewPublicKey:", e.Error(), "\007")
		os.Exit(1)
	}

	var key ecdsa.PrivateKey
	key.D = new(big.Int).SetBytes(priv)
	key.PublicKey = pub_key.PublicKey

	if key.D.Cmp(big.NewInt(0)) == 0 {
		println("pubkey value is zero")
		return false
	}

	if key.D.Cmp(maxKeyVal) != -1 {
		println("pubkey value is too big", hex.EncodeToString(publ))
		return false
	}

	r, s, err := ecdsa.Sign(rand.Reader, &key, hash[:])
	if err != nil {
		println("ecdsa.Sign:", err.Error())
		return false
	}

	ok := ecdsa.Verify(&key.PublicKey, hash[:], r, s)
	if !ok {
		println("The key pair does not verify!")
		return false
	}
	return true
}
Example #17
0
// NewEcdsaPrivateKey creates a new JWK from a EC-DSA private key
func NewEcdsaPrivateKey(pk *ecdsa.PrivateKey) *EcdsaPrivateKey {
	pubkey := NewEcdsaPublicKey(&pk.PublicKey)
	privkey := &EcdsaPrivateKey{EcdsaPublicKey: pubkey}
	privkey.D.SetBytes(i2osp(pk.D, pk.Params().BitSize/8))
	return privkey
}
Example #18
0
func main() {
	id1 := "99375318-11c4-4a77-ba42-f7c08ca7b9d0"
	id2 := "ff375318-11c4-4a77-ba42-f7c08ca7b9d0"
	privkeyHex, err := ioutil.ReadFile(".gn_ecdsa")
	if err != nil {
		panic(err)
	}
	privkey, err := hex.DecodeString(string(privkeyHex[:len(privkeyHex)-1]))
	if err != nil {
		panic(err)
	}

	key := new(ecdsa.PrivateKey)
	key.D = big.NewInt(0)
	key.D.SetBytes(privkey)
	key.PublicKey.Curve = elliptic.P256()
	xb, _ := hex.DecodeString("212d26c6744803803e2f81fa117630a72eaf8a7c12f16e4e1b0188785a57c783256")
	x := big.NewInt(0)
	x.SetBytes(xb)
	key.PublicKey.X = x

	yb, _ := hex.DecodeString("b0802aac16e521569f549092c41c1b295e9ff627534d1b28fe050a37f5280ac9255")
	y := big.NewInt(0)
	y.SetBytes(yb)
	key.PublicKey.Y = y

	ids := map[string]*ecdsa.PublicKey{
		id1: &key.PublicKey,
		id2: &key.PublicKey,
	}
	node1 := gophernet.NewNode(id1, key, 100, ids)
	node2 := gophernet.NewNode(id2, key, 100, ids)

	errChan := make(chan error)
	stopChan := make(chan struct{})
	msgChan1 := make(chan *gophernet.Message, 1)
	msgChan2 := make(chan *gophernet.Message, 1)
	go gophernet.Listen(node1, ":7890", errChan, stopChan, msgChan1)
	go gophernet.Listen(node2, ":7891", errChan, stopChan, msgChan2)

	{
		log.Printf("MAIN: Giving listeners a couple seconds to start.")
		var err error
		select {
		case err = <-errChan:
			log.Printf("MAIN: Error: %v", err)
		case <-time.After(2 * time.Second):
		}

		if err != nil {
			log.Printf("MAIN: At least one error, stopping")
			close(stopChan)
			for err := range errChan {
				log.Print("MAIN: Error: %v", err)
			}
		}
	}

	c, err := net.Dial("tcp", "0.0.0.0:7891")
	if err != nil {
		panic(err)
	}
	p := node2.AddPeer(c)
	go gophernet.Handle(node2.ID, p, node2.DropPeer, node2.GetKey, stopChan, msgChan2)

	node2.Broadcast(&gophernet.Message{})

	select {
	case err = <-errChan:
		log.Printf("MAIN: Error: %v", err)
	case msg := <-msgChan1:
		log.Printf("MAIN: msgChan1: %#v", msg)
	case msg := <-msgChan2:
		log.Printf("MAIN: msgChan2: %#v", msg)
	}
}
Example #19
0
// this function signs either a message or a raw transaction hash
func sign_message() {
	var hash []byte

	if *signhash != "" {
		var er error
		hash, er = hex.DecodeString(*signhash)
		if er != nil {
			println("Incorrect content of -hash parameter")
			println(er.Error())
			return
		}
	}

	ad2s, e := btc.NewAddrFromString(*signaddr)
	if e != nil {
		println(e.Error())
		if *signhash != "" {
			println("Always use -sign <addr> along with -hash <msghash>")
		}
		return
	}

	var privkey *ecdsa.PrivateKey
	var compr bool

	for i := range publ_addrs {
		if publ_addrs[i].Hash160 == ad2s.Hash160 {
			privkey = new(ecdsa.PrivateKey)
			pub, e := btc.NewPublicKey(publ_addrs[i].Pubkey)
			if e != nil {
				println(e.Error())
				return
			}
			privkey.PublicKey = pub.PublicKey
			privkey.D = new(big.Int).SetBytes(priv_keys[i][:])
			compr = compressed_key[i]

			// Sign raw hash?
			if hash != nil {
				txsig := new(btc.Signature)
				txsig.HashType = 0x01
				txsig.R, txsig.S, e = btc.EcdsaSign(privkey, hash)
				if e != nil {
					println(e.Error())
					return
				}
				fmt.Println("PublicKey:", hex.EncodeToString(publ_addrs[i].Pubkey))
				fmt.Println(hex.EncodeToString(txsig.Bytes()))
				return
			}

			break
		}
	}
	if privkey == nil {
		println("You do not have a private key for", ad2s.String())
		return
	}

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

	hash = make([]byte, 32)
	btc.HashFromMessage(msg, hash)

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

	btcsig.R, btcsig.S, e = btc.EcdsaSign(privkey, hash)
	if e != nil {
		println(e.Error())
		return
	}

	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(compr), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}

	rpk = btcsig.RecoverPublicKey(hash[:], 1)
	sa = btc.NewAddrFromPubkey(rpk.Bytes(compr), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		sb[0]++
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}
	println("Something went wrong. The message has not been signed.")
}
Example #20
0
func sign_message() {
	ad2s, e := btc.NewAddrFromString(*signaddr)
	if e != nil {
		println(e.Error())
		return
	}

	var privkey *ecdsa.PrivateKey
	for i := range publ_addrs {
		if publ_addrs[i].Hash160 == ad2s.Hash160 {
			privkey = new(ecdsa.PrivateKey)
			pub, e := btc.NewPublicKey(publ_addrs[i].Pubkey)
			if e != nil {
				println(e.Error())
				return
			}
			privkey.PublicKey = pub.PublicKey
			privkey.D = new(big.Int).SetBytes(priv_keys[i][:])
			break
		}
	}
	if privkey == nil {
		println("You do not have a private key for", ad2s.String())
		return
	}

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

	hash := make([]byte, 32)
	btc.HashFromMessage(msg, hash)

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

	btcsig.R, btcsig.S, e = ecdsa_Sign(privkey, hash)
	if e != nil {
		println(e.Error())
		return
	}

	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(!*uncompressed), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}

	rpk = btcsig.RecoverPublicKey(hash[:], 1)
	sa = btc.NewAddrFromPubkey(rpk.Bytes(!*uncompressed), ad2s.Version)
	if sa.Hash160 == ad2s.Hash160 {
		sb[0]++
		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
		return
	}
	println("Something went wrong. The message has not been signed.")
}
Example #21
0
// prepare a signed transaction
func make_signed_tx() {
	// Make an empty transaction
	tx := new(btc.Tx)
	tx.Version = 1
	tx.Lock_time = 0

	// Select as many inputs as we need to pay the full amount (with the fee)
	var btcsofar uint64
	var inpcnt uint
	for inpcnt = 0; inpcnt < uint(len(unspentOuts)); inpcnt++ {
		uo := UO(unspentOuts[inpcnt])
		// add the input to our transaction:
		tin := new(btc.TxIn)
		tin.Input = *unspentOuts[inpcnt]
		tin.Sequence = 0xffffffff
		tx.TxIn = append(tx.TxIn, tin)

		btcsofar += uo.Value
		if btcsofar >= spendBtc+feeBtc {
			break
		}
	}
	changeBtc = btcsofar - (spendBtc + feeBtc)
	fmt.Printf("Spending %d out of %d outputs...\n", inpcnt+1, len(unspentOuts))

	// Build transaction outputs:
	tx.TxOut = make([]*btc.TxOut, len(sendTo))
	for o := range sendTo {
		tx.TxOut[o] = &btc.TxOut{Value: sendTo[o].amount, Pk_script: sendTo[o].addr.OutScript()}
	}

	if changeBtc > 0 {
		// Add one more output (with the change)
		tx.TxOut = append(tx.TxOut, &btc.TxOut{Value: changeBtc, Pk_script: get_change_addr().OutScript()})
	}

	//fmt.Println("Unsigned:", hex.EncodeToString(tx.Serialize()))

	for in := range tx.TxIn {
		uo := UO(unspentOuts[in])
		var found bool
		for j := range publ_addrs {
			if publ_addrs[j].Owns(uo.Pk_script) {
				pub_key, e := btc.NewPublicKey(publ_addrs[j].Pubkey)
				if e != nil {
					println("NewPublicKey:", e.Error(), "\007")
					os.Exit(1)
				}

				// Load the key (private and public)
				var key ecdsa.PrivateKey
				key.D = new(big.Int).SetBytes(priv_keys[j][:])
				key.PublicKey = pub_key.PublicKey

				//Calculate proper transaction hash
				h := tx.SignatureHash(uo.Pk_script, in, btc.SIGHASH_ALL)
				//fmt.Println("SignatureHash:", btc.NewUint256(h).String())

				// Sign
				r, s, err := ecdsa.Sign(rand.Reader, &key, h)
				if err != nil {
					println("Sign:", err.Error(), "\007")
					os.Exit(1)
				}
				rb := r.Bytes()
				sb := s.Bytes()

				if rb[0] >= 0x80 { // I thinnk this is needed, thought I am not quite sure... :P
					rb = append([]byte{0x00}, rb...)
				}

				if sb[0] >= 0x80 { // I thinnk this is needed, thought I am not quite sure... :P
					sb = append([]byte{0x00}, sb...)
				}

				// Output the signing result into a buffer, in format expected by bitcoin protocol
				busig := new(bytes.Buffer)
				busig.WriteByte(0x30)
				busig.WriteByte(byte(4 + len(rb) + len(sb)))
				busig.WriteByte(0x02)
				busig.WriteByte(byte(len(rb)))
				busig.Write(rb)
				busig.WriteByte(0x02)
				busig.WriteByte(byte(len(sb)))
				busig.Write(sb)
				busig.WriteByte(0x01) // hash type

				// Output the signature and the public key into tx.ScriptSig
				buscr := new(bytes.Buffer)
				buscr.WriteByte(byte(busig.Len()))
				buscr.Write(busig.Bytes())

				buscr.WriteByte(byte(len(publ_addrs[j].Pubkey)))
				buscr.Write(publ_addrs[j].Pubkey)

				// assign:
				tx.TxIn[in].ScriptSig = buscr.Bytes()

				found = true
				break
			}
		}
		if !found {
			fmt.Println("You do not have private key for input number", hex.EncodeToString(uo.Pk_script), "\007")
			os.Exit(1)
		}
	}

	rawtx := tx.Serialize()
	tx.Hash = btc.NewSha2Hash(rawtx)

	hs := tx.Hash.String()
	fmt.Println(hs)

	f, _ := os.Create(hs[:8] + ".txt")
	if f != nil {
		f.Write([]byte(hex.EncodeToString(rawtx)))
		f.Close()
		fmt.Println("Transaction data stored in", hs[:8]+".txt")
	}

	f, _ = os.Create("balance/unspent.txt")
	if f != nil {
		for j := uint(0); j < uint(len(unspentOuts)); j++ {
			if j > inpcnt {
				fmt.Fprintln(f, unspentOuts[j], unspentOutsLabel[j])
			}
		}
		fmt.Println(inpcnt, "spent output(s) removed from 'balance/unspent.txt'")

		var addback int
		for out := range tx.TxOut {
			for j := range publ_addrs {
				if publ_addrs[j].Owns(tx.TxOut[out].Pk_script) {
					fmt.Fprintf(f, "%s-%03d # %.8f / %s\n", tx.Hash.String(), out,
						float64(tx.TxOut[out].Value)/1e8, publ_addrs[j].String())
					addback++
				}
			}
		}
		f.Close()
		if addback > 0 {
			f, _ = os.Create("balance/" + hs + ".tx")
			if f != nil {
				f.Write(rawtx)
				f.Close()
			}
			fmt.Println(addback, "new output(s) appended to 'balance/unspent.txt'")
		}
	}
}
Example #22
0
func multisig_sign() {
	tx := raw_tx_from_file(*rawtx)
	if tx == nil {
		println("ERROR: Cannot decode the raw multisig transaction")
		println("Always use -msign <addr> along with -raw multi2sign.txt")
		return
	}

	ad2s, e := btc.NewAddrFromString(*multisign)
	if e != nil {
		println("BTC addr:", e.Error())
		return
	}

	var privkey *ecdsa.PrivateKey
	//var compr bool

	for i := range publ_addrs {
		if publ_addrs[i].Hash160 == ad2s.Hash160 {
			privkey = new(ecdsa.PrivateKey)
			pub, e := btc.NewPublicKey(publ_addrs[i].Pubkey)
			if e != nil {
				println("PubKey:", e.Error())
				return
			}
			privkey.PublicKey = pub.PublicKey
			privkey.D = new(big.Int).SetBytes(priv_keys[i][:])
			//compr = compressed_key[i]
			break
		}
	}

	if privkey == nil {
		println("You do not know a key for address", ad2s.String())
		return
	}

	for i := range tx.TxIn {
		ms, er := btc.NewMultiSigFromScript(tx.TxIn[i].ScriptSig)
		if er != nil {
			println("WARNING: Input", i, "- not multisig:", er.Error())
			continue
		}
		hash := tx.SignatureHash(ms.P2SH(), i, btc.SIGHASH_ALL)
		//fmt.Println("Input number", i, len(ms.Signatures), " - hash to sign:", hex.EncodeToString(hash))

		btcsig := &btc.Signature{HashType: 0x01}
		btcsig.R, btcsig.S, e = btc.EcdsaSign(privkey, hash)
		if e != nil {
			println(e.Error())
			return
		}

		ms.Signatures = append(ms.Signatures, btcsig)
		tx.TxIn[i].ScriptSig = ms.Bytes()
	}

	// Now re-order the signatures as they shall be:
	for i := range tx.TxIn {
		ms, er := btc.NewMultiSigFromScript(tx.TxIn[i].ScriptSig)
		if er != nil {
			//println(er.Error())
			continue
		}
		hash := tx.SignatureHash(ms.P2SH(), i, btc.SIGHASH_ALL)
		//fmt.Println("Input number", i, " - hash to sign:", hex.EncodeToString(hash))
		//fmt.Println(" ... number of signatures:", len(ms.Signatures))

		var sigs []*btc.Signature
		for ki := range ms.PublicKeys {
			//pk := btc.NewPublicKey(ms.PublicKeys[ki])
			//fmt.Println(ki, hex.EncodeToString(ms.PublicKeys[ki]))
			var sig *btc.Signature
			for si := range ms.Signatures {
				if btc.EcdsaVerify(ms.PublicKeys[ki], ms.Signatures[si].Bytes(), hash) {
					//fmt.Println("Key number", ki, "has signature number", si)
					sig = ms.Signatures[si]
					break
				}
			}
			if sig != nil {
				sigs = append(sigs, sig)
			} else if *verbose {
				fmt.Println("WARNING: Key number", ki, "has no matching signature")
			}

			if !*allowextramsigns && uint(len(sigs)) >= ms.SigsNeeded {
				break
			}

		}

		if len(ms.Signatures) > len(sigs) {
			fmt.Println("WARNING: Some signatures are obsolete and will be removed", len(ms.Signatures), "=>", len(sigs))
		} else if len(ms.Signatures) < len(sigs) {
			fmt.Println("It appears that same key is re-used.", len(sigs)-len(ms.Signatures), "more signatures were added")
		}
		ms.Signatures = sigs
		tx.TxIn[i].ScriptSig = ms.Bytes()
	}

	write_tx_file(tx)
}
Example #23
0
func (service *EMPService) PublishMessage(r *http.Request, args *SendMsg, reply *SendResponse) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	// Nil Check
	if len(args.Sender) == 0 || len(args.Plaintext) == 0 {
		return errors.New("All fields required.")
	}

	var err error

	// Get Addresses
	sendAddr := encryption.StringToAddress(args.Sender)
	if len(sendAddr) == 0 {
		return errors.New("Invalid sender address!")
	}

	sender, err := localdb.GetAddressDetail(objects.MakeHash(sendAddr))
	if err != nil {
		return errors.New(fmt.Sprintf("Error pulling send address from Database: %s", err))
	}
	if sender.Privkey == nil {
		return errors.New("Private Key Required to Publish Message")
	}

	// Create New Message
	msg := new(objects.FullMessage)
	msg.Decrypted = new(objects.DecryptedMessage)
	msg.Encrypted = nil

	txid := make([]byte, len(msg.Decrypted.Txid), cap(msg.Decrypted.Txid))

	// Fill out decrypted message
	n, err := rand.Read(txid)
	if n < len(msg.Decrypted.Txid[:]) || err != nil {
		return errors.New(fmt.Sprintf("Problem with random reader: %s", err))
	}
	copy(msg.Decrypted.Pubkey[:], sender.Pubkey)
	msg.Decrypted.Subject = args.Subject
	msg.Decrypted.MimeType = "text/plain"
	msg.Decrypted.Content = args.Plaintext
	msg.Decrypted.Length = uint32(len(msg.Decrypted.Content))

	// Fill Out Meta Message (save timestamp)
	msg.MetaMessage.Purged = false
	msg.MetaMessage.TxidHash = objects.MakeHash(txid)
	msg.MetaMessage.Sender = sender.String
	msg.MetaMessage.Recipient = "<Subscription Message>"

	// Get Signature
	priv := new(ecdsa.PrivateKey)
	priv.PublicKey.Curve = encryption.GetCurve()
	priv.D = new(big.Int)
	priv.D.SetBytes(sender.Privkey)

	sign := msg.Decrypted.GetBytes()
	sign = sign[:len(sign)-65]
	signHash := objects.MakeHash(sign)

	x, y, err := ecdsa.Sign(rand.Reader, priv, signHash.GetBytes())
	if err != nil {
		return err
	}

	copy(msg.Decrypted.Signature[:], encryption.MarshalPubkey(x, y))

	// Send message and add to sendbox...
	msg.Encrypted = encryption.EncryptPub(service.Config.Log, sender.Privkey, string(msg.Decrypted.GetBytes()))
	msg.MetaMessage.Timestamp = time.Now().Round(time.Second)

	// Now Add Txid
	copy(msg.Decrypted.Txid[:], txid)

	err = localdb.AddUpdateMessage(msg, localdb.SENDBOX)
	if err != nil {
		return err
	}

	sendMsg := new(objects.Message)
	sendMsg.TxidHash = msg.MetaMessage.TxidHash
	sendMsg.AddrHash = objects.MakeHash(sender.Address)
	sendMsg.Timestamp = msg.MetaMessage.Timestamp
	sendMsg.Content = *msg.Encrypted

	service.Config.RecvQueue <- *objects.MakeFrame(objects.PUB, objects.BROADCAST, sendMsg)

	reply.IsSent = true

	// Finish by setting msg's txid
	reply.TxidHash = msg.MetaMessage.TxidHash.GetBytes()
	return nil

}