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

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