// Encrypt plainText into an Encrypted Message using the given public key. func Encrypt(log chan string, dest_pubkey []byte, plainText string) *EncryptedMessage { // Generate New Public/Private Key Pair D1, X1, Y1 := CreateKey(log) // Unmarshal the Destination's Pubkey X2, Y2 := elliptic.Unmarshal(elliptic.P256(), dest_pubkey) // Point Multiply to get new Pubkey PubX, PubY := elliptic.P256().ScalarMult(X2, Y2, D1) // Generate Pubkey hashes PubHash := sha512.Sum512(elliptic.Marshal(elliptic.P256(), PubX, PubY)) PubHash_E := PubHash[:32] PubHash_M := PubHash[32:64] IV, cipherText, _ := SymmetricEncrypt(PubHash_E, plainText) // Generate HMAC mac := hmac.New(sha256.New, PubHash_M) mac.Write(cipherText) HMAC := mac.Sum(nil) ret := new(EncryptedMessage) copy(ret.IV[:], IV[:]) copy(ret.PublicKey[:], elliptic.Marshal(elliptic.P256(), X1, Y1)) ret.CipherText = cipherText copy(ret.HMAC[:], HMAC) return ret }
// Tests whether a message can be signed, and wrapped in plain-text. func TestMessageCleartextSignRecover(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create crypto key: %v", err) } payload := []byte("hello world") msg := NewMessage(payload) if _, err := msg.Wrap(DefaultPoW, Options{ From: key, }); err != nil { t.Fatalf("failed to sign message: %v", err) } if msg.Flags&signatureFlag != signatureFlag { t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag) } if bytes.Compare(msg.Payload, payload) != 0 { t.Fatalf("payload mismatch after signing: have 0x%x, want 0x%x", msg.Payload, payload) } pubKey := msg.Recover() if pubKey == nil { t.Fatalf("failed to recover public key") } p1 := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y) p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y) if !bytes.Equal(p1, p2) { t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1) } }
func MarshalMark(c elliptic.Curve, m *Mark) []byte { bytelen := (c.Params().BitSize + 7) >> 3 pointlen := 1 + 2*bytelen outlen := 2 * pointlen ret := make([]byte, outlen, outlen) abytes := elliptic.Marshal(c, m.ax, m.ay) copy(ret, abytes) bbytes := elliptic.Marshal(c, m.bx, m.by) copy(ret[pointlen:], bbytes) return ret }
// GenerateKeypair generates a public and private ECDSA key, for // later user with NewIssuer or NewVerifier. These are written // as binary files, because PEM is pointless. func GenerateKeypair(filename string) (err error) { priv, err := ecdsa.GenerateKey(curveEll, rand.Reader) if err != nil { return } err = ioutil.WriteFile(filename+".priv", elliptic.Marshal(curveEll, priv.x, priv.y), FileMode(0600)) if err != nil { return } err = ioutil.WriteFile(filename+".pub", elliptic.Marshal(curveEll, pub.x, pub.y), FileMode(0644)) return // TODO(dlg): also write out JWK }
// cmpPublic returns true if the two public keys represent the same pojnt. func cmpPublic(pub1, pub2 PublicKey) bool { if pub1.X == nil || pub1.Y == nil { fmt.Println(ErrInvalidPublicKey.Error()) return false } if pub2.X == nil || pub2.Y == nil { fmt.Println(ErrInvalidPublicKey.Error()) return false } pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y) pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y) return bytes.Equal(pub1Out, pub2Out) }
func FillBallot(c elliptic.Curve, px *big.Int, py *big.Int, entry int, size int) *Ballot { b := new(Ballot) b.boxes = make([]*Checkbox, size, size) for i := 0; i < size; i++ { if i == entry { b.boxes[i] = VoteOne(c, px, py) } else { b.boxes[i] = VoteZero(c, px, py) } } //TODO: add validation //Let A be the sum of all the A, B the sum of all the B //Then we want log_g(A)=log_h(B-g) ax := big.NewInt(0) ay := big.NewInt(0) bx := big.NewInt(0) by := big.NewInt(0) s := big.NewInt(0) for i := 0; i < size; i++ { ax, ay = c.Add(ax, ay, b.boxes[i].ax, b.boxes[i].ay) bx, by = c.Add(bx, by, b.boxes[i].bx, b.boxes[i].by) s.Add(s, b.boxes[i].s) } s.Mod(s, c.Params().N) k, err := rand.Int(rand.Reader, c.Params().N) if err != nil { panic("Not here, not now") } v1x, v1y := c.ScalarBaseMult(k.Bytes()) v2x, v2y := c.ScalarMult(px, py, k.Bytes()) var commit [4][]byte commit[0] = elliptic.Marshal(c, ax, ay) commit[1] = elliptic.Marshal(c, bx, by) commit[2] = elliptic.Marshal(c, v1x, v1y) commit[3] = elliptic.Marshal(c, v2x, v2y) cb := bytes.Join(commit[:], []byte{}) cbytes := sha256.Sum256(cb[:]) b.c = big.NewInt(0) b.c.SetBytes(cbytes[:]) b.c.Mod(b.c, c.Params().N) b.r = big.NewInt(0) //r=k-c*s b.r.Mul(b.c, s) b.r.Sub(k, b.r) b.r.Mod(b.r, c.Params().N) return b }
// marshalECDSASHASigningKeyV1 encodes a private key as a protobuf message. func marshalECDSASHASigningKeyV1(k *ecdsa.PrivateKey) *ECDSA_SHA_SigningKeyV1 { return &ECDSA_SHA_SigningKeyV1{ Curve: NamedEllipticCurve_PRIME256_V1.Enum(), EcPrivate: k.D.Bytes(), EcPublic: elliptic.Marshal(k.Curve, k.X, k.Y), } }
func marshalECDSAKey(priv *ecdsa.PrivateKey) (out []byte, err error) { var eckey ecPrivateKey eckey.Version = 1 eckey.PrivateKey = priv.D.Bytes() switch priv.PublicKey.Curve { case elliptic.P256(): eckey.NamedCurveOID = oidNamedCurveP256 case elliptic.P384(): eckey.NamedCurveOID = oidNamedCurveP384 case elliptic.P521(): eckey.NamedCurveOID = oidNamedCurveP521 default: err = ErrInvalidPrivateKey } pkey := elliptic.Marshal(priv.PublicKey.Curve, priv.PublicKey.X, priv.PublicKey.Y) if pkey == nil { err = ErrInvalidPrivateKey return } eckey.PublicKey = asn1.BitString{ BitLength: len(pkey) * 8, Bytes: pkey, } out, err = asn1.Marshal(eckey) return }
func HandleRegisterBasic(w http.ResponseWriter, r *http.Request) { fmt.Println("HandleRegisterBasic") tmpCurve := elliptic.P256() r.ParseMultipartForm(int64(100)) step := strings.TrimSpace(r.PostFormValue("step")) //state := strings.TrimSpace(r.PostFormValue("state")) if step == "0" { //fmt.Println(step, ":", state) w.Header().Set("Content-Type", "application/json") preInfo, _ := json.Marshal(PreInfo{tmpCurve.Params().Gx.String(), tmpCurve.Params().Gy.String(), tmpCurve.Params().P.String(), tmpCurve.Params().B.String(), tmpCurve.Params().N.String()}) //fmt.Println(string(preInfo)) io.WriteString(w, string(preInfo)) } if step == "1" { //fmt.Println(step, "::", state) pubKey := strings.TrimSpace(r.PostFormValue("pub_key")) fmt.Println(pubKey) uname := strings.TrimSpace(r.PostFormValue("uname")) key := strings.Split(pubKey, ",") pX := new(big.Int) pY := new(big.Int) pX.SetString(key[0], 10) pY.SetString(key[1], 10) dataB = elliptic.Marshal(tmpCurve, pX, pY) fmt.Println(">>>>>>>", uname) fmt.Println(">>>>>>>", dataB) storeData(uname, dataB) _, _ = getData(uname) } }
//Update the named content func (t Tag) Update(hashBytes HID, typeString string) Tag { t.Parents = Parents{t.Hash()} t.HashBytes = hashBytes t.TypeString = typeString //t.nameSegment = t.nameSegment t.Version = newVersion() //t.hkid = t.hkid prikey, err := geterPoster.getPrivateKeyForHkid(t.Hkid) if err != nil { log.Panic("You don't seem to own this Domain") } ObjectHash := t.genTagHash( t.HashBytes, t.TypeString, t.NameSegment, t.Version, t.Parents, t.Hkid, ) ecdsaprikey := ecdsa.PrivateKey(*prikey) r, s, _ := ecdsa.Sign(rand.Reader, &ecdsaprikey, ObjectHash) t.Signature = elliptic.Marshal(elliptic.P521(), r, s) return t }
//NewTag build a new tag with the initial content func NewTag( HashBytes HID, TypeString string, nameSegment string, tparent Parents, hkid HKID, ) Tag { prikey, _ := geterPoster.getPrivateKeyForHkid(hkid) version := newVersion() if tparent == nil { tparent = Parents{Blob{}.Hash()} } ObjectHash := Tag{}.genTagHash( HashBytes, TypeString, nameSegment, version, tparent, hkid, ) ecdsaprikey := ecdsa.PrivateKey(*prikey) r, s, _ := ecdsa.Sign(rand.Reader, &ecdsaprikey, ObjectHash) signature := elliptic.Marshal(elliptic.P521(), r, s) t := Tag{HashBytes, TypeString, nameSegment, version, tparent, hkid, signature} return t }
func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey { pk := &PublicKey{ CreationTime: creationTime, PubKeyAlgo: PubKeyAlgoECDSA, PublicKey: pub, ec: new(ecdsaKey), } switch pub.Curve { case elliptic.P256(): pk.ec.oid = oidCurveP256 case elliptic.P384(): pk.ec.oid = oidCurveP384 case elliptic.P521(): pk.ec.oid = oidCurveP521 default: panic("unknown elliptic curve") } pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes)) pk.setFingerPrintAndKeyId() return pk }
func TestMessage(t *testing.T) { log := make(chan string, 100) priv, x, y := encryption.CreateKey(log) pub := elliptic.Marshal(elliptic.P256(), x, y) address := encryption.GetAddress(log, x, y) msg := new(Message) msg.AddrHash = MakeHash(address) msg.TxidHash = MakeHash([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) msg.Timestamp = time.Now().Round(time.Second) msg.Content = *encryption.Encrypt(log, pub, "Hello World!") mBytes := msg.GetBytes() if mBytes == nil { fmt.Println("Error Encoding Message!") t.FailNow() } msg2 := new(Message) msg2.FromBytes(mBytes) if string(msg2.AddrHash.GetBytes()) != string(msg.AddrHash.GetBytes()) || string(msg2.TxidHash.GetBytes()) != string(msg.TxidHash.GetBytes()) || msg2.Timestamp.Unix() != msg.Timestamp.Unix() { fmt.Println("Message Header incorrect: ", msg2) t.FailNow() } if string(encryption.Decrypt(log, priv, &msg.Content)[:12]) != "Hello World!" { fmt.Println("Message content incorrect: ", string(encryption.Decrypt(log, priv, &msg.Content)[:12])) t.Fail() } }
// marshalECDSASHAVerifyingKeyV1 encodes a public key as a protobuf message. func marshalECDSASHAVerifyingKeyV1(k *ecdsa.PublicKey) *ECDSA_SHA_VerifyingKeyV1 { return &ECDSA_SHA_VerifyingKeyV1{ Curve: NamedEllipticCurve_PRIME256_V1.Enum(), EcPublic: elliptic.Marshal(k.Curve, k.X, k.Y), } }
func pubkeyDump(w indent.Writer, cert *x509.Certificate) { switch cert.PublicKeyAlgorithm { case x509.ECDSA: w.Printf("Public Key Algorithm: %s\n", w.Bold("ECDSA")) pub, ok := cert.PublicKey.(*ecdsa.PublicKey) if !ok { w.Println(w.Bold("[unrecognizable]")) return } w.Headerf("Public Key: (%s)\n", w.Bold("%d bits", pub.Params().BitSize)) w.PrintHex(elliptic.Marshal(pub.Curve, pub.X, pub.Y)) w.Dedent() w.Printf("Curve: %s\n", EcdsaCurveName[pub.Curve]) return case x509.RSA: w.Printf("Public Key Algorithm: RSA\n") case x509.DSA: w.Printf("Public Key Algorithm: DSA\n") default: w.Printf("Public Key Algorithm: Unknown (type %d)\n", cert.PublicKeyAlgorithm) } b, err := x509.MarshalPKIXPublicKey(cert.PublicKey) w.Headerf("Public Key:\n") if err != nil { w.Printf("[unrecognizable]\n") } else { w.PrintHex(b) } w.Dedent() }
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { switch pub := pub.(type) { case *rsa.PublicKey: publicKeyBytes, err = asn1.Marshal(rsaPublicKey{ N: pub.N, E: pub.E, }) publicKeyAlgorithm.Algorithm = oidPublicKeyRSA // This is a NULL parameters value which is technically // superfluous, but most other code includes it and, by // doing this, we match their public key hashes. publicKeyAlgorithm.Parameters = asn1.RawValue{ Tag: 5, } case *ecdsa.PublicKey: publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) oid, ok := oidFromNamedCurve(pub.Curve) if !ok { return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") } publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA var paramBytes []byte paramBytes, err = asn1.Marshal(oid) if err != nil { return } publicKeyAlgorithm.Parameters.FullBytes = paramBytes default: return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported") } return publicKeyBytes, publicKeyAlgorithm, nil }
// Encrypt secures and authenticates its input using the public key // using ECDHE with AES-128-CBC-HMAC-SHA1. func Encrypt(pub *ecdsa.PublicKey, in []byte) (out []byte, err error) { ephemeral, err := ecdsa.GenerateKey(Curve(), rand.Reader) if err != nil { return } x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, ephemeral.D.Bytes()) if x == nil { return nil, errors.New("Failed to generate encryption key") } shared := sha256.Sum256(x.Bytes()) iv, err := symcrypt.MakeRandom(16) if err != nil { return } paddedIn := padding.AddPadding(in) ct, err := symcrypt.EncryptCBC(paddedIn, iv, shared[:16]) if err != nil { return } ephPub := elliptic.Marshal(pub.Curve, ephemeral.PublicKey.X, ephemeral.PublicKey.Y) out = make([]byte, 1+len(ephPub)+16) out[0] = byte(len(ephPub)) copy(out[1:], ephPub) copy(out[1+len(ephPub):], iv) out = append(out, ct...) h := hmac.New(sha1.New, shared[16:]) h.Write(iv) h.Write(ct) out = h.Sum(out) return }
// Convert ECC-256 Public Key to an EMP address (raw 25 bytes). func GetAddress(log chan string, x, y *big.Int) []byte { pubKey := elliptic.Marshal(elliptic.P256(), x, y) ripemd := ripemd160.New() sum := sha512.Sum384(pubKey) sumslice := make([]byte, sha512.Size384, sha512.Size384) for i := 0; i < sha512.Size384; i++ { sumslice[i] = sum[i] } ripemd.Write(sumslice) appender := ripemd.Sum(nil) appender = appender[len(appender)-20:] address := make([]byte, 1, 1) // Version 0x01 address[0] = 0x01 address = append(address, appender...) sum = sha512.Sum384(address) sum = sha512.Sum384(sum[:]) for i := 0; i < 4; i++ { address = append(address, sum[i]) } return address }
// FIXME(dlg): This is hideous. func arrayForPublicKey(pub *ecdsa.PublicKey) string { raw := elliptic.Marshal(pub.Curve, pub.X, pub.Y) vals := make([]string, len(raw)) for i, b := range raw { vals[i] = strconv.Itoa(int(b)) } return "[" + strings.Join(vals, ", ") + "]" }
func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) { var x, y *big.Int e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand) if err != nil { return nil, err } return elliptic.Marshal(e.curve, x, y), nil }
// Insert adds a private key to the agent. func (c *client) insertKey(s interface{}, comment string, constraints []byte) error { var req []byte switch k := s.(type) { case *rsa.PrivateKey: if len(k.Primes) != 2 { return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes)) } k.Precompute() req = ssh.Marshal(rsaKeyMsg{ Type: ssh.KeyAlgoRSA, N: k.N, E: big.NewInt(int64(k.E)), D: k.D, Iqmp: k.Precomputed.Qinv, P: k.Primes[0], Q: k.Primes[1], Comments: comment, Constraints: constraints, }) case *dsa.PrivateKey: req = ssh.Marshal(dsaKeyMsg{ Type: ssh.KeyAlgoDSA, P: k.P, Q: k.Q, G: k.G, Y: k.Y, X: k.X, Comments: comment, Constraints: constraints, }) case *ecdsa.PrivateKey: nistID := fmt.Sprintf("nistp%d", k.Params().BitSize) req = ssh.Marshal(ecdsaKeyMsg{ Type: "ecdsa-sha2-" + nistID, Curve: nistID, KeyBytes: elliptic.Marshal(k.Curve, k.X, k.Y), D: k.D, Comments: comment, Constraints: constraints, }) default: return fmt.Errorf("agent: unsupported key type %T", s) } // if constraints are present then the message type needs to be changed. if len(constraints) != 0 { req[0] = agentAddIdConstrained } resp, err := c.call(req) if err != nil { return err } if _, ok := resp.(*successAgentMsg); ok { return nil } return errors.New("agent: failure") }
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { var curveid uint16 Curve: for _, c := range clientHello.supportedCurves { switch c { case curveP256: ka.curve = elliptic.P256() curveid = c break Curve case curveP384: ka.curve = elliptic.P384() curveid = c break Curve case curveP521: ka.curve = elliptic.P521() curveid = c break Curve } } if curveid == 0 { return nil, errors.New("tls: no supported elliptic curves offered") } var x, y *big.Int var err error ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand()) if err != nil { return nil, err } ecdhePublic := elliptic.Marshal(ka.curve, x, y) // http://tools.ietf.org/html/rfc4492#section-5.4 serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) serverECDHParams[0] = 3 // named curve serverECDHParams[1] = byte(curveid >> 8) serverECDHParams[2] = byte(curveid) serverECDHParams[3] = byte(len(ecdhePublic)) copy(serverECDHParams[4:], ecdhePublic) md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams) sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1) if err != nil { return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) } skx := new(serverKeyExchangeMsg) skx.key = make([]byte, len(serverECDHParams)+2+len(sig)) copy(skx.key, serverECDHParams) k := skx.key[len(serverECDHParams):] k[0] = byte(len(sig) >> 8) k[1] = byte(len(sig)) copy(k[2:], sig) return skx, nil }
func eciesEncrypt(rand io.Reader, pub *ecdsa.PublicKey, s1, s2 []byte, plain []byte) ([]byte, error) { params := pub.Curve // Select an ephemeral elliptic curve key pair associated with // elliptic curve domain parameters params priv, Rx, Ry, err := elliptic.GenerateKey(pub.Curve, rand) //fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes())) //fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes())) // Convert R=(Rx,Ry) to an octed string R bar // This is uncompressed Rb := elliptic.Marshal(pub.Curve, Rx, Ry) // Derive a shared secret field element z from the ephemeral secret key k // and convert z to an octet string Z z, _ := params.ScalarMult(pub.X, pub.Y, priv) Z := z.Bytes() //fmt.Printf("Z %s\n", utils.EncodeBase64(Z)) // generate keying data K of length ecnKeyLen + macKeyLen octects from Z // ans s1 kE := make([]byte, 32) kM := make([]byte, 32) hkdf := hkdf.New(primitives.GetDefaultHash(), Z, s1, nil) _, err = hkdf.Read(kE) if err != nil { return nil, err } _, err = hkdf.Read(kM) if err != nil { return nil, err } // Use the encryption operation of the symmetric encryption scheme // to encrypt m under EK as ciphertext EM EM, err := aesEncrypt(kE, plain) // Use the tagging operation of the MAC scheme to compute // the tag D on EM || s2 mac := hmac.New(primitives.GetDefaultHash(), kM) mac.Write(EM) if len(s2) > 0 { mac.Write(s2) } D := mac.Sum(nil) // Output R,EM,D ciphertext := make([]byte, len(Rb)+len(EM)+len(D)) //fmt.Printf("Rb %s\n", utils.EncodeBase64(Rb)) //fmt.Printf("EM %s\n", utils.EncodeBase64(EM)) //fmt.Printf("D %s\n", utils.EncodeBase64(D)) copy(ciphertext, Rb) copy(ciphertext[len(Rb):], EM) copy(ciphertext[len(Rb)+len(EM):], D) return ciphertext, nil }
// kexECDH performs Elliptic Curve Diffie-Hellman key exchange as // described in RFC 5656, section 4. func (c *ClientConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, hostKeyAlgo string) (*kexResult, error) { ephKey, err := ecdsa.GenerateKey(curve, c.config.rand()) if err != nil { return nil, err } kexInit := kexECDHInitMsg{ ClientPubKey: elliptic.Marshal(curve, ephKey.PublicKey.X, ephKey.PublicKey.Y), } serialized := marshal(msgKexECDHInit, kexInit) if err := c.writePacket(serialized); err != nil { return nil, err } packet, err := c.readPacket() if err != nil { return nil, err } var reply kexECDHReplyMsg if err = unmarshal(&reply, packet, msgKexECDHReply); err != nil { return nil, err } x, y := elliptic.Unmarshal(curve, reply.EphemeralPubKey) if x == nil { return nil, errors.New("ssh: elliptic.Unmarshal failure") } if !validateECPublicKey(curve, x, y) { return nil, errors.New("ssh: ephemeral server key not on curve") } // generate shared secret secret, _ := curve.ScalarMult(x, y, ephKey.D.Bytes()) hashFunc := ecHash(curve) h := hashFunc.New() writeString(h, magics.clientVersion) writeString(h, magics.serverVersion) writeString(h, magics.clientKexInit) writeString(h, magics.serverKexInit) writeString(h, reply.HostKey) writeString(h, kexInit.ClientPubKey) writeString(h, reply.EphemeralPubKey) K := make([]byte, intLength(secret)) marshalInt(K, secret) h.Write(K) return &kexResult{ H: h.Sum(nil), K: K, HostKey: reply.HostKey, Signature: reply.Signature, Hash: hashFunc, }, nil }
// PubkeyID returns a marshaled representation of the given public key. func PubkeyID(pub *ecdsa.PublicKey) NodeID { var id NodeID pbytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y) if len(pbytes)-1 != len(id) { panic(fmt.Errorf("need %d bit pubkey, got %d bits", (len(id)+1)*8, len(pbytes))) } copy(id[:], pbytes[1:]) return id }
// Tests whether a message can be properly signed and encrypted. func TestMessageFullCrypto(t *testing.T) { fromKey, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create sender crypto key: %v", err) } toKey, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to create recipient crypto key: %v", err) } payload := []byte("hello world") msg := NewMessage(payload) envelope, err := msg.Wrap(DefaultPoW, Options{ From: fromKey, To: &toKey.PublicKey, }) if err != nil { t.Fatalf("failed to encrypt message: %v", err) } if msg.Flags&signatureFlag != signatureFlag { t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag) } if len(msg.Signature) == 0 { t.Fatalf("no signature found for signed message") } out, err := envelope.Open(toKey) if err != nil { t.Fatalf("failed to open encrypted message: %v", err) } if !bytes.Equal(out.Payload, payload) { t.Error("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload) } pubKey := out.Recover() if pubKey == nil { t.Fatalf("failed to recover public key") } p1 := elliptic.Marshal(crypto.S256(), fromKey.PublicKey.X, fromKey.PublicKey.Y) p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y) if !bytes.Equal(p1, p2) { t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1) } }
func WritePublicCertificate(w io.Writer, cert PublicCertificate) error { buf := elliptic.Marshal(curve, cert.X, cert.Y) // 57 bytes if _, err := w.Write(buf); err != nil { return err } return nil }
func WriteSignature(w io.Writer, sig Signature) error { buf := elliptic.Marshal(curve, sig.r, sig.s) // 57 bytes if _, err := w.Write(buf); err != nil { return err } return nil }
func IsValidBallot(c elliptic.Curve, px *big.Int, py *big.Int, b *Ballot) bool { valid := true for i := 0; i < len(b.boxes); i++ { valid = valid && IsValidBox(c, b.boxes[i], px, py) } if !valid { return false } //Time to go do some work //TODO: fix all additions (elsewhere in file to use fact //that Go handles identity as (0,0) ax := big.NewInt(0) ay := big.NewInt(0) bx := big.NewInt(0) by := big.NewInt(0) for i := 0; i < len(b.boxes); i++ { ax, ay = c.Add(ax, ay, b.boxes[i].ax, b.boxes[i].ay) bx, by = c.Add(bx, by, b.boxes[i].bx, b.boxes[i].by) } t := big.NewInt(0) t.Neg(c.Params().Gy) t.Mod(t, c.Params().P) bgx, bgy := c.Add(bx, by, c.Params().Gx, t) v1x, v1y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, b.r.Bytes(), ax, ay, b.c.Bytes()) v2x, v2y := doublescalarmult(c, px, py, b.r.Bytes(), bgx, bgy, b.c.Bytes()) var commit [4][]byte commit[0] = elliptic.Marshal(c, ax, ay) commit[1] = elliptic.Marshal(c, bx, by) commit[2] = elliptic.Marshal(c, v1x, v1y) commit[3] = elliptic.Marshal(c, v2x, v2y) cb := bytes.Join(commit[:], []byte{}) cbytes := sha256.Sum256(cb[:]) challenge := big.NewInt(0) challenge.SetBytes(cbytes[:]) challenge.Mod(challenge, c.Params().N) if challenge.Cmp(b.c) != 0 { return false } else { return true } }
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { if ka.curve == nil { return nil, nil, errors.New("missing ServerKeyExchange message") } priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand()) if err != nil { return nil, nil, err } ka.clientPrivKey = make([]byte, len(priv)) copy(ka.clientPrivKey, priv) ka.clientX = mx ka.clientY = my x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv) preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) xBytes := x.Bytes() copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) serialized := elliptic.Marshal(ka.curve, mx, my) ckx := new(clientKeyExchangeMsg) var body []byte ckx.ciphertext = make([]byte, 1+len(serialized)) ckx.ciphertext[0] = byte(len(serialized)) body = ckx.ciphertext[1:] copy(body, serialized) return preMasterSecret, ckx, nil }