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

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