Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rpc_nonce_request.go 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package rpc
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/binary"
  6. "time"
  7. "github.com/juju/errors"
  8. )
  9. const (
  10. RPCNonceSeqNo = -2
  11. rpcNonceLength = 16
  12. rpcNonceKeySelectorLength = 4
  13. rpcNonceCryptoTSLength = 4
  14. rpcNonceTagLength = 4
  15. rpcNonceCryptoAESLength = 4
  16. rpcNonceRequestLength = rpcNonceTagLength + rpcNonceKeySelectorLength +
  17. rpcNonceCryptoAESLength + rpcNonceCryptoTSLength + rpcNonceLength
  18. )
  19. var (
  20. rpcNonceTag = [rpcNonceTagLength]byte{0xaa, 0x87, 0xcb, 0x7a}
  21. rpcNonceCryptoAESTag = [rpcNonceCryptoAESLength]byte{0x01, 0x00, 0x00, 0x00}
  22. )
  23. type RPCNonceRequest struct {
  24. KeySelector [rpcNonceKeySelectorLength]byte
  25. CryptoTS [rpcNonceCryptoTSLength]byte
  26. Nonce [rpcNonceLength]byte
  27. }
  28. func (r *RPCNonceRequest) Bytes() []byte {
  29. buf := &bytes.Buffer{}
  30. buf.Grow(rpcNonceRequestLength)
  31. buf.Write(rpcNonceTag[:])
  32. buf.Write(r.KeySelector[:])
  33. buf.Write(rpcNonceCryptoAESTag[:])
  34. buf.Write(r.CryptoTS[:])
  35. buf.Write(r.Nonce[:])
  36. return buf.Bytes()
  37. }
  38. func NewRPCNonceRequest(proxySecret []byte) (*RPCNonceRequest, error) {
  39. var nonce [rpcNonceLength]byte
  40. var keySelector [rpcNonceKeySelectorLength]byte
  41. var cryptoTS [rpcNonceCryptoTSLength]byte
  42. if _, err := rand.Read(nonce[:]); err != nil {
  43. return nil, errors.Annotate(err, "Cannot generate nonce")
  44. }
  45. copy(keySelector[:], proxySecret)
  46. timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
  47. binary.LittleEndian.PutUint32(cryptoTS[:], uint32(timestamp))
  48. return &RPCNonceRequest{
  49. KeySelector: keySelector,
  50. CryptoTS: cryptoTS,
  51. Nonce: nonce,
  52. }, nil
  53. }