12 def dump_keccak_state(what
, state
):
13 buf
= CAT
.ReadBuffer(state
+ CAT
.ByteString
.zero(200 - len(state
)))
14 print ";; %s [round 0]" % what
15 print ";; uncomplemented state..."
17 print ";;\t%s" %
" ".join(["%016x" % buf
.getu64l() for j
in xrange(5)])
20 class Strobe (object):
21 def __init__(me
, sec
= 128, _copy
= None):
23 me
.k
= CAT
.Keccak1600()
24 me
.r
= (1600 - 2*sec
)/8
27 buf
= CAT
.WriteBuffer()
28 buf
.putu8(1).putu8(me
.r
)
30 buf
.putu8(1).putu8(12*8).put('STROBEv1.0.2')
31 ##dump_keccak_state("init", buf.contents)
32 me
.k
.mix(buf
.contents
).step()
33 me
.buf
= CAT
.WriteBuffer()
34 me
.mask
= me
.k
.extract(me
.r
- 2)
35 ##dump_keccak_state("final", me.mask)
41 me
.buf
= CAT
.WriteBuffer().put(_copy
.buf
.contents
)
42 me
.mask
= me
._copy
.mask
45 me
.buf
.putu8(me
.p0
); me
.p0
= 0
46 if me
.buf
.size
== me
.r
- 1: me
.buf
.putu8(0x84)
47 else: me
.buf
.putu8(0x04).zero(me
.r
- me
.buf
.size
- 1).putu8(0x80)
48 ##dump_keccak_state("buffer", me.buf.contents)
49 ##dump_keccak_state("init", me.buf.contents ^ me.k.extract(me.r))
50 me
.k
.mix(me
.buf
.contents
).step()
51 me
.mask
= me
.k
.extract(me
.r
- 2)
52 ##dump_keccak_state("final", me.mask)
53 me
.buf
= CAT
.WriteBuffer()
55 def process(me
, op
, input):
59 if not me
.f
&INIT
: me
.f |
= INIT |
(op
&I
)
61 me
.buf
.putu8(me
.p0
); me
.p0
= me
.buf
.size
62 if me
.buf
.size
>= me
.r
- 2: me
._crank()
64 if op
&C
or me
.buf
.size
>= me
.r
- 2: me
._crank()
66 if op
&(I | T
) == I
or op
&(I | A
) == 0: buf
= CAT
.ByteString
.zero(input)
67 else: buf
= CAT
.ByteString(input)
68 out
= CAT
.WriteBuffer()
69 i
, j
, sz
= 0, me
.buf
.size
, len(buf
)
73 n
= min(spare
, sz
- i
); x
= buf
[i
:i
+ n
]; i
+= n
74 if not op
&C
: out
.put(x
); me
.buf
.put(x
)
76 y
= x ^ me
.mask
[j
:j
+ n
]; out
.put(y
)
77 if op
&I
or not op
&T
: me
.buf
.put(y
)
79 if n
== spare
: me
._crank(); j
= 0
81 if op
&(I | A | C | T
) != (I | C | T
): return out
.contents
82 elif out
.contents
== CAT
.ByteString
.zero(out
.size
): return me
83 else: raise ValueError, 'verify failed'
88 st0
.process(A | M
, 'testing')
89 st1
.process(A | M
, 'testing')
91 print 'prf(10) -> %s' %
hex(st0
.process(I | A | C
, 10))
92 st1
.process(I | A | C
, 10)
95 st0
.process(A
, 'Hello')
96 st1
.process(A
, 'Hello')
98 c0
= st0
.process(A | C | T
, 'World');
99 st1
.process(I | A | C | T
, c0
)
100 print 'encout("World") -> %s' %
hex(c0
)
102 print 'clrout("foo")'
103 st0
.process(A | T
, 'foo');
104 st1
.process(I | A | T
, 'foo')
107 st1
.process(A | T
, 'bar')
108 st0
.process(I | A | T
, 'bar')
110 m1
= st0
.process(I | A | C | T
, 'baz')
111 st1
.process(A | C | T
, m1
) # backwards in time
112 print 'encin("baz") -> %s' %
hex(m1
)
114 for i
in xrange(200):
115 c
= st0
.process(A | C | T
, i
*'X')
116 m
= st1
.process(I | A | C | T
, c
)
117 print " 0 encout\n\t=%s\n\t!%s;" %
(i
*'X', hex(c
))
118 print " 1 encin\n\t!%s\n\t=%s;" %
(hex(c
), i
*'X')
120 r0
= st0
.process(I | A | C
, 123)
121 r1
= st1
.process(I | A | C
, 123)
122 print 'prf(123) -> %s' %
hex(r0
)
125 t
= st0
.process(C | T
, 16)
126 print 'macout(16) -> %s' %
hex(t
)
127 st1
.process(I | C | T
, t
)
129 k
= 'this is my super-secret key'
130 print 'key("%s")' % k
131 st0
.process(A | C
, k
)
132 st1
.process(A | C
, k
)
134 r0
= st0
.process(I | A | C
, 32)
135 r1
= st1
.process(I | A | C
, 32)
136 print 'prf(32) -> %s' %
hex(r0
)
143 t0
= CAT
.bytes('b2084ebdfabd50768c91eebc190132cc')
144 st0
.process(I | C | T
, t0
)
145 t1
= st1
.process(C | T
, 16)
147 print 'macin(%s)' %
hex(t0
)