Subject: Re: [GOST] Формат подписи CMS в pygost

From: Sergey Matveev <[email-masked]>
Date: Fri, 1 Dec 2017 11:10:34 +0300

*** Гневашев Дмитрий [2017-12-01 10:46]:
>В инструкции по подписыванию документов принимающей стороны дана ссылка на
>пункт 3.1 RFC 4490, в котором указано, что подпись состоит из 64 октетов,
>первый 32 из которых - это число s, а вторые - r'. Приведённая выше строка,
>видимо, меняет местами эти два числа в подписи. Какой смысл вкладывался в эту
>строку? Может существуют какие-то два представления подписи, одна из которых
>"инвертированная", а другая нет, и этот тест был написан на каких-то реальных
>данных, которые должны инвертироваться?

В этом тесте используется тестовый вектор из RFC 5832 (GOST R
34.10-2001: Digital Signature Algorithm). Пункт 6.1 этого RFC говорит:

   Step 6 - calculate the binary vectors R and S, corresponding to r
   and s, and determine the digital signature zeta = (R || S) as a
   concatenation of these two binary vectors.

То есть, в этом RFC они представляют подпись как конкатенацию из R и S.
В тестовом коде мы видим что signature является как-раз конкатенацией
этих двух значений.

-----# 1 [                                pygost/test_gost3410.py ]-----
  31 class Test341001(TestCase):
  32     def test_rfc(self):
  33         """ Test vector from :rfc:`5832`
  34         """
  59         signature = bytes(bytearray((
  60             0x41, 0xAA, 0x28, 0xD2, 0xF1, 0xAB, 0x14, 0x82,
  61             0x80, 0xCD, 0x9E, 0xD5, 0x6F, 0xED, 0xA4, 0x19,
  62             0x74, 0x05, 0x35, 0x54, 0xA4, 0x27, 0x67, 0xB8,
  63             0x3A, 0xD0, 0x43, 0xFD, 0x39, 0xDC, 0x04, 0x93,
  64             0x01, 0x45, 0x6C, 0x64, 0xBA, 0x46, 0x42, 0xA1,
  65             0x65, 0x3C, 0x23, 0x5A, 0x98, 0xA6, 0x02, 0x49,
  66             0xBC, 0xD6, 0xD3, 0xF7, 0x46, 0xB6, 0x31, 0xDF,
  67             0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40
  68         )))
  70         signature = signature[32:] + signature[:32]
---------------------------------- >8 ----------------------------------

Однако, RFC 4490 (Using the GOST 28147-89, GOST R 34.11-94, GOST R
34.10-94, and GOST R 34.10-2001 Algorithms with CMS) в разделе 3.2
говорит:

   The signature algorithm GOST R 34.10-2001 generates a digital
   signature in the form of two 256-bit numbers, r and s.  Its octet
   string representation consists of 64 octets, where the first 32
   octets contain the big-endian representation of s and the second 32
   octets contain the big-endian representation of r.

То есть первым идёт S, а потом R, наоборот относительно RFC 5832.

RFC 4491 (Using the GOST R 34.10-94, GOST R 34.10-2001, and GOST R
34.11-94 Algorithms with X.509 and CRL) в разделе 2.2.2 говорит:

   The signature algorithm GOST R 34.10-2001 generates a digital
   signature in the form of two 256-bit numbers, r and s.  Its octet
   string representation consists of 64 octets, where the first 32
   octets contain the big-endian representation of s and the second 32
   octets contain the big-endian representation of r.

То есть, тоже сначала S, потом R. Так как на практике большинство
наверняка будут использовать X.509/CMS/подобные форматы, то
pygost.gost3410.sign делает формат подписи именно в этом виде --
наиболее распространённом на практике: сначала S, потом R. Но, в тестах
все данные заданы в том виде, котором представлены в документе с этими
тестами -- чтобы можно было открыть RFC/PDF и визуально убедиться что в
тестах именно те же самые векторы. Поэтому например в 34.11 тестах есть
кручение хэшей -- чтобы визуально они совпадали с тем что записано в
RFC, чтобы людям было проще читать/проверять код.

Повторюсь, pygost делает подписи совместимыми с RFC 4490/4491 (ну и
соответствующими RFC для алгоримов 2012-го года) -- для удобства, так
как эти форматы (X.509/CMS) наверняка и будут использоваться на деле.
Но тесты записываются в виде удобном для визуального сравнения с
документами.

-- 
Sergey Matveev (http://www.stargrave.org/)
OpenPGP: CF60 E89A 5923 1E76 E263  6422 AE1A 8109 E498 57EF