62b4cde357c4d59fcac9003d9341a2e75bd8b719
4 from struct
import unpack
, pack
5 from itertools
import izip
10 ###--------------------------------------------------------------------------
17 yield [things
[i
] for i
in ii
]
19 if j
== k
- 1: lim
= n
32 try: return POLYMAP
[nbits
]
34 base
= C
.GF(0).setbit(nbits
).setbit(0)
35 for k
in xrange(1, nbits
, 2):
36 for cc
in combs(range(1, nbits
), k
):
37 p
= base
+ sum(C
.GF(0).setbit(c
) for c
in cc
)
38 if p
.irreduciblep(): POLYMAP
[nbits
] = p
; return p
39 raise ValueError, nbits
42 return C
.ByteString
.zero(n
)
44 def mul_blk_gf(m
, x
, p
): return ((C
.GF
.loadb(m
)*x
)%p
).storeb((p
.nbits
+ 6)/8)
49 except StopIteration: raise ValueError, 'empty iter'
54 except StopIteration: lastp
= True
58 if len(x
): return hex(x
)
63 if isinstance(ksz
, C
.KeySZSet
): kk
= ksz
.set
64 elif isinstance(ksz
, C
.KeySZRange
): kk
= range(ksz
.min, ksz
.max, ksz
.mod
)
65 elif isinstance(ksz
, C
.KeySZAny
): kk
= range(64); sel
= [0]
66 kk
= list(kk
); kk
= kk
[:]
68 while n
and len(sel
) < 4:
71 kk
[i
], kk
[n
] = kk
[n
], kk
[i
]
80 return C
.ByteString(m
)
84 if r
: m
+= '\x80' + Z(r
- 1)
85 return C
.ByteString(m
)
89 while (i
&1) == 0: i
>>= 1; j
+= 1
93 v
, i
, n
= [], 0, len(x
)
95 v
.append(C
.ByteString(x
[i
:i
+ w
]))
97 return v
, C
.ByteString(x
[i
:])
103 if len(tl
) == w
: v
.append(tl
); tl
= EMPTY
106 def dummygen(bc
): return []
110 ###--------------------------------------------------------------------------
113 class RC6Cipher (type):
114 def __new__(cls
, w
, r
):
115 name
= 'rc6-%d/%d' %
(w
, r
)
116 me
= type(name
, (RC6Base
,), {})
121 me
.keysz
= C
.KeySZRange(me
.blksz
, 1, 255, 1)
125 return w
.bit_length() - 1
128 m0
, m1
= C
.MP(0).setbit(w
- n
) - 1, C
.MP(0).setbit(n
) - 1
129 return ((x
&m0
) << n
) |
(x
>> (w
- n
))&m1
132 m0
, m1
= C
.MP(0).setbit(n
) - 1, C
.MP(0).setbit(w
- n
) - 1
133 return ((x
&m0
) << (w
- n
)) |
(x
>> n
)&m1
135 class RC6Base (object):
138 P400
= C
.MP(0xb7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef324e7738926cfbe5f4bf8d8d8c31d763da06)
139 Q400
= C
.MP(0x9e3779b97f4a7c15f39cc0605cedc8341082276bf3a27251f86c6a11d0c18e952767f0b153d27b7f0347045b5bf1827f0188)
143 ## Build the magic numbers.
144 P
= me
.P400
>> (400 - me
.w
)
146 Q
= me
.Q400
>> (400 - me
.w
)
148 M
= C
.MP(0).setbit(me
.w
) - 1
150 ## Convert the key into words.
152 c
= (len(k
) + wb
- 1)/wb
153 kb
, ktl
= blocks(k
, me
.w
/8)
154 L
= map(C
.MP
.loadl
, kb
+ [ktl
])
157 ## Build the subkey table.
160 S
= [(P
+ i
*Q
)&M
for i
in xrange(n
)]
162 ##for j in xrange(c):
163 ## print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0'))
164 ##for i in xrange(n):
165 ## print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0'))
170 for s
in xrange(3*max(c
, n
)):
171 A
= S
[i
] = rol(me
.w
, S
[i
] + A
+ B
, 3)
172 B
= L
[j
] = rol(me
.w
, L
[j
] + A
+ B
, (A
+ B
)%(1 << me
.d
))
173 ##print 'S[%3d] = %s' % (i, hex(S[i]).upper()[2:].rjust(2*wb, '0'))
174 ##print 'L[%3d] = %s' % (j, hex(L[j]).upper()[2:].rjust(2*wb, '0'))
182 M
= C
.MP(0).setbit(me
.w
) - 1
183 a
, b
, c
, d
= map(C
.MP
.loadl
, blocks0(x
, me
.blksz
/4)[0])
186 ##print 'B = %s' % (hex(b).upper()[2:].rjust(me.w/4, '0'))
187 ##print 'D = %s' % (hex(d).upper()[2:].rjust(me.w/4, '0'))
188 for i
in xrange(2, 2*me
.r
+ 2, 2):
189 t
= rol(me
.w
, 2*b
*b
+ b
, me
.d
)
190 u
= rol(me
.w
, 2*d
*d
+ d
, me
.d
)
191 a
= (rol(me
.w
, a ^ t
, u
%(1 << me
.d
)) + me
.s
[i
+ 0])&M
192 c
= (rol(me
.w
, c ^ u
, t
%(1 << me
.d
)) + me
.s
[i
+ 1])&M
193 ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0'))
194 ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0'))
195 a
, b
, c
, d
= b
, c
, d
, a
196 a
= (a
+ me
.s
[2*me
.r
+ 2])&M
197 c
= (c
+ me
.s
[2*me
.r
+ 3])&M
198 ##print 'A = %s' % (hex(a).upper()[2:].rjust(me.w/4, '0'))
199 ##print 'C = %s' % (hex(c).upper()[2:].rjust(me.w/4, '0'))
200 return C
.ByteString(a
.storel(me
.blksz
/4) + b
.storel(me
.blksz
/4) +
201 c
.storel(me
.blksz
/4) + d
.storel(me
.blksz
/4))
204 M
= C
.MP(0).setbit(me
.w
) - 1
205 a
, b
, c
, d
= map(C
.MP
.loadl
, blocks0(x
, me
.blksz
/4))
206 c
= (c
- me
.s
[2*me
.r
+ 3])&M
207 a
= (a
- me
.s
[2*me
.r
+ 2])&M
208 for i
in xrange(2*me
.r
+ 1, 1, -2):
209 a
, b
, c
, d
= d
, a
, b
, c
210 u
= rol(me
.w
, 2*d
*d
+ d
, me
.d
)
211 t
= rol(me
.w
, 2*b
*b
+ b
, me
.d
)
212 c
= ror(me
.w
, (c
- me
.s
[i
+ 1])&M
, t
%(1 << me
.d
)) ^ u
213 a
= ror(me
.w
, (a
- me
.s
[i
+ 0])&M
, u
%(1 << me
.d
)) ^ t
214 a
= (a
+ s
[2*me
.r
+ 2])&M
215 c
= (c
+ s
[2*me
.r
+ 3])&M
216 return C
.ByteString(a
.storel(me
.blksz
/4) + b
.storel(me
.blksz
/4) +
217 c
.storel(me
.blksz
/4) + d
.storel(me
.blksz
/4))
219 for (w
, r
) in [(8, 16), (16, 16), (24, 16), (32, 16),
220 (32, 20), (48, 16), (64, 16), (96, 16), (128, 16),
221 (192, 16), (256, 16), (400, 16)]:
222 CUSTOM
['rc6-%d/%d' %
(w
, r
)] = RC6Cipher(w
, r
)
224 ###--------------------------------------------------------------------------
228 blksz
= E
.__class__
.blksz
232 m0
= mul_blk_gf(L
, 2, p
)
233 m1
= mul_blk_gf(m0
, 2, p
)
237 blksz
= E
.__class__
.blksz
238 m0
, m1
= omac_masks(E
)
239 print 'L = %s' %
hex(E
.encrypt(Z(blksz
)))
240 print 'm0 = %s' %
hex(m0
)
241 print 'm1 = %s' %
hex(m1
)
243 print 'v%d = %s' %
(t
, hex(E
.encrypt(C
.MP(t
).storeb(blksz
))))
244 print 'z%d = %s' %
(t
, hex(omac(E
, t
, '')))
247 blksz
= E
.__class__
.blksz
248 m0
, m1
= omac_masks(E
)
250 if t
is not None: m
= C
.MP(t
).storeb(blksz
) + m
251 v
, tl
= blocks(m
, blksz
)
252 for x
in v
: a
= E
.encrypt(a ^ x
)
255 a
= E
.encrypt(a ^ tl ^ m0
)
257 pad
= pad10star(tl
, blksz
)
258 a
= E
.encrypt(a ^ pad ^ m1
)
262 if VERBOSE
: dump_omac(E
)
263 return omac(E
, None, m
),
270 ###--------------------------------------------------------------------------
274 blksz
= E
.__class__
.blksz
277 while y
.size
< len(m
):
278 y
.put(E
.encrypt(c
.storeb(blksz
)))
280 return C
.ByteString(m
) ^ C
.ByteString(y
)[:len(m
)]
282 ###--------------------------------------------------------------------------
295 return C
.ByteString(y
)
300 u
, v
= C
.GF
.loadl(gcm_mangle(x
)), C
.GF
.loadl(gcm_mangle(y
))
302 return gcm_mangle(z
.storel(w
))
307 u
= C
.GF
.loadl(gcm_mangle(x
))
309 return gcm_mangle(z
.storel(w
))
311 def gcm_ctr(E
, m
, c0
):
314 c
, = unpack('>L', c0
[-4:])
315 while y
.size
< len(m
):
317 y
.put(E
.encrypt(pre
+ pack('>L', c
)))
318 return C
.ByteString(m
) ^ C
.ByteString(y
)[:len(m
)]
320 def g(what
, x
, m
, a0
= None):
322 if a0
is None: a
= Z(n
)
325 for b
in blocks0(m
, n
)[0]:
326 a
= gcm_mul(a ^ b
, x
)
327 if VERBOSE
: print '%s[%d] = %s -> %s' %
(what
, i
, hex(b
), hex(a
))
332 return C
.ByteString(x
+ Z(-len(x
)%w
))
334 def gcm_lens(w
, a
, b
):
337 return C
.ByteString(C
.MP(a
).storeb(n
) + C
.MP(b
).storeb(n
))
339 def ghash(whata
, whatb
, x
, a
, b
):
341 ha
= g(whata
, x
, gcm_pad(w
, a
))
342 hb
= g(whatb
, x
, gcm_pad(w
, b
))
344 hc
= gcm_mul(ha
, gcm_pow(x
, (len(b
) + w
- 1)/w
)) ^ hb
345 if VERBOSE
: print '%s || %s -> %s' %
(whata
, whatb
, hex(hc
))
348 return g(whatb
, x
, gcm_lens(w
, 8*len(a
), 8*len(b
)), hc
)
350 def gcmenc(E
, n
, h
, m
, tsz
= None):
351 w
= E
.__class__
.blksz
353 if VERBOSE
: print 'x = %s' %
hex(x
)
354 if len(n
) + 4 == w
: c0
= C
.ByteString(n
+ pack('>L', 1))
355 else: c0
= ghash('?', 'n', x
, EMPTY
, n
)
356 if VERBOSE
: print 'c0 = %s' %
hex(c0
)
357 y
= gcm_ctr(E
, m
, c0
)
358 t
= ghash('h', 'y', x
, h
, y
) ^ E
.encrypt(c0
)
361 def gcmdec(E
, n
, h
, y
, t
):
362 w
= E
.__class__
.blksz
364 if VERBOSE
: print 'x = %s' %
hex(x
)
365 if len(n
) + 4 == w
: c0
= C
.ByteString(n
+ pack('>L', 1))
366 else: c0
= ghash('?', 'n', x
, EMPTY
, n
)
367 if VERBOSE
: print 'c0 = %s' %
hex(c0
)
368 m
= gcm_ctr(E
, y
, c0
)
369 tt
= ghash('h', 'y', x
, h
, y
) ^ E
.encrypt(c0
)
370 if t
== tt
: return m
,
374 return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1),
375 (bc
.blksz
, 3*bc
.blksz
, 3*bc
.blksz
),
376 (bc
.blksz
- 4, bc
.blksz
+ 3, 3*bc
.blksz
+ 9),
377 (bc
.blksz
- 1, 3*bc
.blksz
- 5, 3*bc
.blksz
+ 5)]
379 ###--------------------------------------------------------------------------
382 def stbe(n
, w
): return C
.MP(n
).storeb(w
)
384 def ccm_fmthdr(blksz
, n
, hsz
, msz
, tsz
):
387 q
= blksz
- len(n
) - 1
392 b
.putu8(f
).put(n
).put(stbe(msz
, q
))
394 q
= blksz
- len(n
) - 1
397 f |
= (tsz
- 2)/2 << 3
399 b
.putu8(f
).put(n
).put(stbe(msz
, q
))
401 q
= blksz
- len(n
) - 2
406 b
.putu8(f0
).putu8(f1
).put(n
).put(stbe(msz
, q
))
408 if VERBOSE
: print 'hdr = %s' %
hex(b
)
411 def ccm_fmtctr(blksz
, n
, i
= 0):
413 if blksz
== 8 or blksz
== 16:
414 q
= blksz
- len(n
) - 1
415 b
.putu8(q
- 1).put(n
).put(stbe(i
, q
))
417 q
= blksz
- len(n
) - 2
418 b
.putu8(0).putu8(q
).put(n
).put(stbe(i
, q
))
420 if VERBOSE
: print 'ctr = %s' %
hex(b
)
423 def ccmaad(b
, h
, blksz
):
426 elif hsz
< 0xfffe: b
.putu16(hsz
)
427 elif hsz
<= 0xffffffff: b
.putu16(0xfffe).putu32(hsz
)
428 else: b
.putu16(0xffff).putu64(hsz
)
429 b
.put(h
); b
.zero((-b
.size
)%blksz
)
431 def ccmenc(E
, n
, h
, m
, tsz
= None):
432 blksz
= E
.__class__
.blksz
433 if tsz
is None: tsz
= blksz
435 b
.put(ccm_fmthdr(blksz
, n
, len(h
), len(m
), tsz
))
437 b
.put(m
); b
.zero((-b
.size
)%blksz
)
440 v
, _
= blocks0(b
, blksz
)
445 print 'b[%d] = %s' %
(i
, hex(x
))
446 print 'a[%d] = %s' %
(i
+ 1, hex(a
))
448 y
= ctr(E
, a
+ m
, ccm_fmtctr(blksz
, n
))
449 return C
.ByteString(y
[blksz
:]), C
.ByteString(y
[0:tsz
])
451 def ccmdec(E
, n
, h
, y
, t
):
452 blksz
= E
.__class__
.blksz
455 b
.put(ccm_fmthdr(blksz
, n
, len(h
), len(y
), tsz
))
457 mm
= ctr(E
, t
+ Z(blksz
- tsz
) + y
, ccm_fmtctr(blksz
, n
))
458 u
, m
= C
.ByteString(mm
[0:tsz
]), C
.ByteString(mm
[blksz
:])
459 b
.put(m
); b
.zero((-b
.size
)%blksz
)
462 v
, _
= blocks0(b
, blksz
)
467 print 'b[%d] = %s' %
(i
, hex(x
))
468 print 'a[%d] = %s' %
(i
+ 1, hex(a
))
470 if u
== a
[:tsz
]: return m
,
475 return [(bsz
- 5, 0, 0, 4), (bsz
- 5, 1, 0, 4), (bsz
- 5, 0, 1, 4),
476 (bsz
/2 + 1, 3*bc
.blksz
, 3*bc
.blksz
),
477 (bsz
/2 + 1, 3*bc
.blksz
- 5, 3*bc
.blksz
+ 5)]
479 ###--------------------------------------------------------------------------
482 def eaxenc(E
, n
, h
, m
, tsz
= None):
484 print 'k = %s' %
hex(k
)
485 print 'n = %s' %
hex(n
)
486 print 'h = %s' %
hex(h
)
487 print 'm = %s' %
hex(m
)
489 if tsz
is None: tsz
= E
.__class__
.blksz
495 print 'c0 = %s' %
hex(c0
)
496 print 'ht = %s' %
hex(ht
)
497 print 'yt = %s' %
hex(yt
)
498 return y
, C
.ByteString((c0 ^ ht ^ yt
)[:tsz
])
500 def eaxdec(E
, n
, h
, y
, t
):
502 print 'k = %s' %
hex(k
)
503 print 'n = %s' %
hex(n
)
504 print 'h = %s' %
hex(h
)
505 print 'y = %s' %
hex(y
)
506 print 't = %s' %
hex(t
)
513 print 'c0 = %s' %
hex(c0
)
514 print 'ht = %s' %
hex(ht
)
515 print 'yt = %s' %
hex(yt
)
516 if t
== (c0 ^ ht ^ yt
)[:len(t
)]: return m
,
520 return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1),
521 (bc
.blksz
, 3*bc
.blksz
, 3*bc
.blksz
),
522 (bc
.blksz
- 1, 3*bc
.blksz
- 5, 3*bc
.blksz
+ 5)]
524 ###--------------------------------------------------------------------------
527 class struct (object):
528 def __init__(me
, **kw
):
529 me
.__dict__
.update(kw
)
531 binarg
= struct(mk
= R
.block
, parse
= C
.bytes
, show
= safehex
)
532 intarg
= struct(mk
= lambda x
: x
, parse
= int, show
= None)
534 MODEMAP
= { 'eax-enc': (eaxgen
, 3*[binarg
] + [intarg
], eaxenc
),
535 'eax-dec': (dummygen
, 4*[binarg
], eaxdec
),
536 'ccm-enc': (ccmgen
, 3*[binarg
] + [intarg
], ccmenc
),
537 'ccm-dec': (dummygen
, 4*[binarg
], ccmdec
),
538 'cmac': (cmacgen
, [binarg
], cmac
),
539 'gcm-enc': (gcmgen
, 3*[binarg
] + [intarg
], gcmenc
),
540 'gcm-dec': (dummygen
, 4*[binarg
], gcmdec
) }
544 for d
in CUSTOM
, C
.gcprps
:
546 except KeyError: pass
548 if bc
is None: raise KeyError, argv
[2]
551 gen
, argty
, func
= MODEMAP
[mode
]
552 if mode
.endswith('-enc'): mode
= mode
[:-4]
553 print '%s-%s {' %
(bc
.name
, mode
)
554 for ksz
in keylens(bc
.keysz
):
555 for argvals
in gen(bc
):
557 args
= [t
.mk(a
) for t
, a
in izip(argty
, argvals
)]
558 rets
= func(bc(k
), *args
)
559 print ' %s' % safehex
(k
)
560 for t
, a
in izip(argty
, args
):
561 if t
.show
: print ' %s' % t
.show(a
)
562 for r
, lastp
in with_lastp(rets
):
563 print ' %s%s' %
(safehex(r
), lastp
and ';' or '')
568 gen
, argty
, func
= MODEMAP
[mode
]
569 args
= [t
.parse(a
) for t
, a
in izip(argty
, argv
[4:])]
570 rets
= func(bc(k
), *args
)
572 if r
is None: print "X"
575 ###----- That's all, folks --------------------------------------------------