algorithms.c: Add bindings for STROBE.
[catacomb-python] / t / t-algorithms.py
index 856470a..fd239fb 100644 (file)
@@ -845,6 +845,96 @@ class TestKeccak (HashBufferTestMixin):
   def test_kmac256(me): me.check_kmac(C.KMAC256, 64)
 
 ###--------------------------------------------------------------------------
+class TestStrobe (HashBufferTestMixin):
+
+  HASHMETH = "process"
+
+  def test_strobe(me):
+
+    ## Construction.
+    s0 = C.Strobe()
+    s1 = C.Strobe(128)
+    me.assertEqual(s0.l, 128)
+    me.assertEqual(s1.l, 128)
+    C.Strobe(704)
+    me.assertRaises(ValueError, C.Strobe, 127)
+    me.assertRaises(ValueError, C.Strobe, 736)
+    me.assertEqual(s0.role, C.STRBRL_UNDCD)
+    me.assertEqual(s1.role, C.STRBRL_UNDCD)
+
+    ## `process' vs operation-specific functions.  (This follows Hamburg's
+    ## `Concurrence' test.)
+    h = T.bin("testing")
+    s0.ad(h, f = "M"); s1.begin(C.STROBE_AD | C.STRBF_M).process(h).done()
+
+    t = s1.begin(C.STRBF_I | C.STRBF_A | C.STRBF_C).process(10); s1.done()
+    me.assertEqual(s0.prf(10), t)
+    me.assertEqual(t, C.bytes("8a13a189683bf5678170"))
+
+    h = T.bin("Hello")
+    s0.ad(h); s1.begin(" A   ").process(h).done()
+
+    m = T.bin("World"); c = s0.encout(m)
+    me.assertFalse(s1.activep)
+    m1 = s1.begin("IACT ").process(c); me.assertTrue(s1.activep);
+    s1.done(); me.assertFalse(s1.activep)
+    me.assertEqual(c, C.bytes("123bfbee34"))
+    me.assertEqual(m1, m)
+    me.assertEqual(s0.role, C.STRBRL_INIT)
+    me.assertEqual(s1.role, C.STRBRL_RESP)
+
+    m = T.bin("foo"); s0.clrout(m); s1.begin("IA T ").process(m).done()
+    m = T.bin("bar"); s0.clrin(m);  s1.begin(" A T ").process(m).done()
+
+    c = T.bin("baz"); m = s0.encin(c)
+    c1 = s1.begin(" ACT ").process(m); s1.done()
+    me.assertEqual(m, C.bytes("15e518"))
+    me.assertEqual(c1, c)
+
+    xxx = T.bin(199*"X")
+    for i in T.range(200):
+      c = s0.begin(" ACT ").process(xxx[:i]); s0.done(); s1.encin(c)
+
+    t = s1.begin("IAC  ").process(123); s1.done()
+    me.assertEqual(t, C.bytes
+      ("45476fc0806aee35e864c4f18e6ba62bd3eb1b1e8bef9042b30b0f15d00c3e9f"
+       "5d5904ab789d4c67eaed582473c15aa4424f11d52b21a296b36db3392e2ecbb2"
+       "dc6963bafba3b23882d061f1d335e86e470e8d819591bf0c223e24b925751d04"
+       "f789fc73bc55f7d2b3ed4881c625aa6321d31511b13f6d5e4ce54a"))
+    me.assertEqual(s0.prf(123), t)
+
+    ## Copying and MAC.
+    s2 = s0.copy()
+    t = s0.macout(16)
+    me.assertEqual(t, C.bytes("171419608e11e7c907d493209e17f26b"))
+    me.assertEqual(s2.begin("  CT ").process(16), t); s2.done()
+    s3 = s1.copy(); me.assertFalse(s3.macin(~t))
+    s3 = s1.copy(); me.assertTrue(s3.macin(t))
+    s3 = s1.copy(); me.assertFalse(s3.begin("I CT ").process(~t).done())
+    me.assertTrue(s1.begin("I CT ").process(t).done())
+
+    ## Test the remaining operations.  (From the Catacomb test vectors.)
+    k = T.bin("this is my super-secret key")
+    s0.key(k); s1.begin(" AC   ").process(k).done()
+
+    t = s1.begin(C.STROBE_PRF).process(32); s1.done()
+    me.assertEqual(t, C.bytes
+      ("5418e0f0ee7f982bbbdc2b4bbf49425d0088abfa98ee21d8ad8a3610d15ebb68"))
+    me.assertEqual(s0.prf(32), t)
+
+    s0.ratchet(32); s1.begin("C").process(32).done()
+
+    t = s1.begin("  CT ").process(16); s1.done()
+    me.assertEqual(t, C.bytes("b2084ebdfabd50768c91eebc190132cc"))
+    me.assertTrue(s0.macin(t))
+
+  def test_hashbuffer(me):
+    def mkhash(hsz):
+      s = C.Strobe(256).begin(C.STROBE_AD)
+      return s, lambda: s.done().macout(16)
+    me.check_hashbuffer(mkhash)
+
+###--------------------------------------------------------------------------
 class TestPRP (T.GenericTestMixin):
   """Test pseudorandom permutations (PRPs)."""