poly1305.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. rs = (0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91
  2. ,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25
  3. ,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65
  4. ,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80)
  5. msg = (0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
  6. ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
  7. ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
  8. ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
  9. ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
  10. ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
  11. ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
  12. ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
  13. ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
  14. ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
  15. ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
  16. ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
  17. ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
  18. ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
  19. ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
  20. ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
  21. ,0xe3,0x55,0xa5)
  22. tag = (0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
  23. ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9)
  24. print len(msg)
  25. WORD = 0xffffffff
  26. def add(x, y):
  27. u = 0
  28. r = [0] * 17
  29. for i in range(17):
  30. u += (x[i] + y[i]) & WORD
  31. r[i] = u & 0xff
  32. u >>= 8
  33. return r
  34. def reduce(x):
  35. r = list(x)
  36. u = 0
  37. for i in range(16):
  38. u += r[i]
  39. r[i] = u & 0xff
  40. u >>= 8
  41. u += r[16]
  42. r[16] = u & 3
  43. u = 5 * (u >> 2)
  44. for i in range(16):
  45. u += r[i]
  46. r[i] = u & 0xff
  47. u >>= 8
  48. u += r[16]
  49. r[16] = u
  50. return r
  51. def modmul(x, y):
  52. r = [0] * 17
  53. for i in range(17):
  54. u = 0
  55. for j in range(i + 1):
  56. u += (x[j] * y[i - j]) & WORD
  57. for j in range(i + 1, 17):
  58. u += (320 * x[j] * y[i + 17 - j]) & WORD
  59. r[i] = u
  60. return reduce(r)
  61. def dump(why, v):
  62. print '%s = %s' % (why, ' '.join('%08x' % x for x in v))
  63. def freeze(x):
  64. # -2^130 - 5 in twos complement
  65. negative_130_5 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252)
  66. r = add(x, negative_130_5)
  67. dump('minusp', r)
  68. negative = bool(x[16] >> 7)
  69. if negative:
  70. return r
  71. else:
  72. return x
  73. def poly1305(msg, rs):
  74. r, s = list(rs[:16]), list(rs[16:])
  75. r[3] &= 15
  76. r[4] &= 252
  77. r[7] &= 15
  78. r[8] &= 252
  79. r[11] &= 15
  80. r[12] &= 252
  81. r[15] &= 15
  82. r.append(0)
  83. h = [0] * 17
  84. dump('r-init', r)
  85. dump('h-init', h)
  86. block = 0
  87. for offs in range(0, len(msg), 16):
  88. print '--- block %d ---' % block
  89. block += 1
  90. c = list(msg[offs:offs+16])
  91. c.append(1)
  92. while len(c) != 17: c.append(0)
  93. dump('c', c)
  94. h = add(h, c)
  95. dump('after-add', h)
  96. h = modmul(h, r)
  97. dump('after-mul', h)
  98. dump('end-block', h)
  99. h = freeze(h)
  100. dump('h', h)
  101. s.append(0)
  102. h = add(h, s)
  103. dump('final', h)
  104. return h[:16]
  105. r = poly1305(msg, rs)
  106. print repr([hex(x) for x in r])