7a04f298d2
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
55 lines
1.9 KiB
Go
55 lines
1.9 KiB
Go
package srp
|
|
|
|
import (
|
|
"io"
|
|
"math/big"
|
|
|
|
"github.com/go-faster/errors"
|
|
)
|
|
|
|
// computeXV computes following numbers
|
|
//
|
|
// `x = PH2(password, salt1, salt2)`
|
|
// `v = pow(g, x) mod p`
|
|
//
|
|
// TDLib uses terms `clientSalt` for `salt1` and `serverSalt` for `salt2`.
|
|
func (s SRP) computeXV(password, clientSalt, serverSalt []byte, g, p *big.Int) (x, v *big.Int) {
|
|
// `x = PH2(password, salt1, salt2)`
|
|
x = new(big.Int).SetBytes(s.secondary(password, clientSalt, serverSalt))
|
|
// `v = pow(g, x) mod p`
|
|
v = new(big.Int).Exp(g, x, p)
|
|
return x, v
|
|
}
|
|
|
|
// NewHash computes new user password hash using parameters from server.
|
|
//
|
|
// See https://core.telegram.org/api/srp#setting-a-new-2fa-password.
|
|
//
|
|
// TDLib implementation:
|
|
// See https://github.com/tdlib/td/blob/fa8feefed70d64271945e9d5fd010b957d93c8cd/td/telegram/PasswordManager.cpp#L57.
|
|
//
|
|
// TDesktop implementation:
|
|
// See https://github.com/telegramdesktop/tdesktop/blob/v3.4.8/Telegram/SourceFiles/core/core_cloud_password.cpp#L68.
|
|
func (s SRP) NewHash(password []byte, i Input) (hash, newSalt []byte, _ error) {
|
|
// Generate a new new_password_hash using the KDF algorithm specified in the new_settings,
|
|
// just append 32 sufficiently random bytes to the salt1, first. Proceed as for checking passwords with SRP,
|
|
// just stop at the generation of the v parameter, and use it as new_password_hash:
|
|
p := new(big.Int).SetBytes(i.P)
|
|
if err := checkInput(i.G, p); err != nil {
|
|
return nil, nil, errors.Wrap(err, "validate algo")
|
|
}
|
|
|
|
// Make a copy.
|
|
newClientSalt := append([]byte(nil), i.Salt1...)
|
|
newClientSalt = append(newClientSalt, make([]byte, 32)...)
|
|
// ... append 32 sufficiently random bytes to the salt1 ...
|
|
if _, err := io.ReadFull(s.random, newClientSalt[len(newClientSalt)-32:]); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
_, v := s.computeXV(password, newClientSalt, i.Salt2, big.NewInt(int64(i.G)), p)
|
|
// As usual in big endian form, padded to 2048 bits.
|
|
padded, _ := s.pad256FromBig(v)
|
|
return padded[:], newClientSalt, nil
|
|
}
|