// saltgen is a function that generates all the keys and salts given a length // and an initial salt. func saltgen(salt []byte, count int) [][]byte { salts := make([][]byte, count) for i := 0; i < count; i++ { salts[i] = salt salt = abstract.Sum(network.Suite, salt) } return salts }
func (v *stateVector) addShuffle(suite abstract.Suite, shuf *shuffler, rand abstract.Cipher) error { // Get the previous shuffle state. i := len(v.States) prev := v.States[i-1] X, Y := prev.X, prev.Dec // Compute the new base using the public keys of the remaining // servers. H := suite.Point().Null() for j := i - 1; j < shuf.N; j++ { H = suite.Point().Add(H, shuf.HH[j]) } // Do a key-shuffle. Xbar, Ybar, prover := shuffle.Shuffle(suite, nil, H, X, Y, rand) prf, err := proof.HashProve(suite, "PairShuffle", rand, prover) if err != nil { return err } // Seeded random for the decryption proof. seed := abstract.Sum(suite, prf) prfRand := suite.Cipher(seed) // Scratch space for calculations. zs := suite.Secret() zp := suite.Point() // Peel off a layer of encryption. dec := make([]abstract.Point, len(Xbar)) decPrf := make([]*decryptionProof, len(Xbar)) for j := range Xbar { // Decryption. zp.Mul(Xbar[j], shuf.h) dec[j] = suite.Point().Sub(Ybar[j], zp) // Decryption proof. t := suite.Secret().Pick(rand) T := suite.Point().Mul(Xbar[j], t) c := suite.Secret().Pick(prfRand) s := suite.Secret().Add(t, zs.Mul(c, shuf.h)) decPrf[j] = &decryptionProof{T, s} } // Append the new state to the state vector. state := &shuffleState{H, Xbar, Ybar, dec, prf, decPrf} v.States = append(v.States, state) return nil }
func (s *shuffler) signStateVector(state *stateVector) ([]byte, error) { rand := s.suite.Cipher(abstract.RandomKey) st := state.States for i := 1; i < len(st); i++ { S, Sbar := st[i-1], st[i] X, Y := S.X, S.Dec Xbar, Ybar := Sbar.X, Sbar.Y H, prf := Sbar.G, Sbar.Prf // Verify the shuffle. verifier := shuffle.Verifier(s.suite, nil, H, X, Y, Xbar, Ybar) err := proof.HashVerify(s.suite, "PairShuffle", verifier, prf) if err != nil { panic("verify failed") return nil, err } // Verify the decryption. seed := abstract.Sum(s.suite, prf) verRand := s.suite.Cipher(seed) dec, decPrf := Sbar.Dec, Sbar.DecPrf // Scratch space for calculations. pair, c := s.suite.Point(), s.suite.Secret() zp := s.suite.Point() for j := range dec { pair.Sub(Ybar[j], dec[j]) c.Pick(verRand) T := decPrf[j].T ss := decPrf[j].S if !zp.Mul(Xbar[j], ss).Equal(T.Add(T, pair.Mul(pair, c))) { return nil, errors.New("invalid decryption proof") } } } bytes, _ := protobuf.Encode(state) return anon.Sign(s.suite, rand, bytes, anon.Set{s.H}, nil, 0, s.h), nil }
// PubId returns the base64-encoded HashId for this KeyPair's public key. func (p *KeyPair) PubId() string { buf, _ := p.Public.MarshalBinary() hash := abstract.Sum(p.Suite, buf) return base64.RawURLEncoding.EncodeToString(hash) }
func (rh *RandHound) hash(bytes ...[]byte) []byte { return abstract.Sum(rh.Suite(), bytes...) }
// getpass contacts the guard servers, then gets the passwords and // reconstructs the secret keys. func getpass(c *cli.Context, uid []byte, epoch []byte, pass string) { if getuser(uid) == nil { log.Fatal("Wrong username") } keys := make([]string, len(db.Cothority.List)) blind := make([]byte, 12) _, err := rand.Read(blind) log.ErrFatal(err) blinds := saltgen(blind, len(db.Cothority.List)) iv := getuser(uid).Iv // pwhash is the password hash that will be sent to the guard servers // with Gu and bi. pwhash := abstract.Sum(network.Suite, []byte(pass), getuser(uid).Salt) GuHash := abstract.Sum(network.Suite, uid, epoch) // creating stream for Scalar.Pick from the hash blocky, err := aes.NewCipher(iv) log.ErrFatal(err) GuStream := cipher.NewCTR(blocky, iv) gupoint := network.Suite.Point() Gu, _ := gupoint.Pick(GuHash, GuStream) for i, si := range db.Cothority.List { cl := guard.NewClient() // blankpoints needed for computations. blankpoint := network.Suite.Point() blankscalar := network.Suite.Scalar() // pwbytes and blindbytes are actually scalars that are // initialized to the values of the bytes. pwbytes := network.Suite.Scalar() pwbytes.SetBytes(pwhash) blindbytes := network.Suite.Scalar() blindbytes.SetBytes(blinds[i]) // The following sections of the code perform the computations // to Create Xi, here called sendy. blankscalar.Add(pwbytes, blindbytes).MarshalBinary() _, err := blankpoint.Mul(Gu, blankscalar.Mul(pwbytes, blindbytes)).MarshalBinary() sendy := blankpoint.Mul(Gu, blankscalar.Mul(pwbytes, blindbytes)) rep, cerr := cl.SendToGuard(si, uid, epoch, sendy) log.ErrFatal(cerr) // This section of the program removes the blinding factor from // the Zi for storage. reply, err := blankpoint.Mul(rep.Msg, blankscalar.Inv(blindbytes)).MarshalBinary() log.ErrFatal(err) // This section Xors the data with the response. block, err := aes.NewCipher(reply) stream := cipher.NewCTR(block, getuser(uid).Iv) msg := make([]byte, len([]byte(getuser(uid).Keys[i]))) stream.XORKeyStream(msg, []byte(getuser(uid).Keys[i])) keys[i] = string(msg) } k := s.Combine(keys) if len(k) == 0 { log.Fatal("You entered the wrong password") } block, err := aes.NewCipher([]byte(k)) log.ErrFatal(err) aesgcm, err := cipher.NewGCM(block) log.ErrFatal(err) plaintext, err := aesgcm.Open(nil, getuser(uid).Salt, getuser(uid).Data, nil) log.ErrFatal(err) log.Print(string(plaintext)) }
func set(c *cli.Context, uid []byte, epoch []byte, password string, userdata []byte) { mastersalt := make([]byte, 12) _, err := rand.Read(mastersalt) log.ErrFatal(err) k := make([]byte, 32) _, err = rand.Read(k) log.ErrFatal(err) // secretkeys is the Shamir Secret share of the keys. secretkeys := s.Create(2, len(db.Cothority.List), string(k)) blind := make([]byte, 12) _, err = rand.Read(blind) log.ErrFatal(err) blinds := saltgen(blind, len(db.Cothority.List)) iv := make([]byte, 16) _, err = rand.Read(iv) log.ErrFatal(err) // pwhash is the password hash that will be sent to the guard servers // with Gu and bi. pwhash := abstract.Sum(network.Suite, []byte(password), mastersalt) GuHash := abstract.Sum(network.Suite, uid, epoch) // creating stream for Scalar.Pick from the hash. blocky, err := aes.NewCipher(iv) log.ErrFatal(err) GuStream := cipher.NewCTR(blocky, iv) gupoint := network.Suite.Point() Gu, _ := gupoint.Pick(GuHash, GuStream) responses := make([][]byte, len(db.Cothority.List)) keys := make([][]byte, len(db.Cothority.List)) for i, si := range db.Cothority.List { cl := guard.NewClient() // blankpoints needed to call the functions. blankpoint := network.Suite.Point() blankscalar := network.Suite.Scalar() // Initializing the variables pwbytes and blindbytes, which are // scalars with the values of pwhash and blinds[i]. pwbytes := network.Suite.Scalar() pwbytes.SetBytes(pwhash) blindbytes := network.Suite.Scalar() blindbytes.SetBytes(blinds[i]) // this next part performs all necessary computations to create // Xi, here called sendy. blankscalar.Add(pwbytes, blindbytes).Bytes() sendy := blankpoint.Mul(Gu, blankscalar.Mul(pwbytes, blindbytes)) rep, cerr := cl.SendToGuard(si, uid, epoch, sendy) log.ErrFatal(cerr) reply := blankpoint.Mul(rep.Msg, blankscalar.Inv(blindbytes)) responses[i], err = reply.MarshalBinary() log.ErrFatal(err) block, err := aes.NewCipher(responses[i]) log.ErrFatal(err) stream := cipher.NewCTR(block, iv) msg := make([]byte, 88) stream.XORKeyStream(msg, []byte(secretkeys[i])) keys[i] = msg } // This is the code that seals the user data using the master key // and saves it to the db. block, _ := aes.NewCipher(k) aesgcm, _ := cipher.NewGCM(block) ciphertext := aesgcm.Seal(nil, mastersalt, userdata, nil) db.Users = append(db.Users, User{uid, mastersalt, keys, ciphertext, iv}) }