Created
March 22, 2020 20:49
-
-
Save rqu1/f236b68a2b3efd9b22eacd3f7003cd15 to your computer and use it in GitHub Desktop.
dst80 python implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def bit(x,n): return (x>>n)&1 | |
def bit_slice(x,msb,lsb): return (x&((2<<msb)-1))>>lsb | |
def bv2i(*args): | |
o=0 | |
for i in args: o=(o<<1)|i | |
return o | |
def fa(x): return bit(0x3a35acc5,x) | |
def fb(x): return bit(0xac35742e,x) | |
def fc(x): return bit(0xb81d8bd1,x) | |
def fd(x): return bit(0x5acc335a,x) | |
def fe(x): return bit(0xe247,x) | |
def fg(x): return bit(0x4e72,x) | |
def h(x): return (0x1f9826f4>>(2*x))&3 | |
#def h(x): return [0,1,3,3,2,1,2,0,0,2,1,2,3,3,1,0][x] | |
def fn(s,k): | |
return ( | |
fd(bv2i(bit(s,32),bit(k,32),bit(s,24),bit(k,24),bit(s,16))), | |
fe(bv2i(bit(k,16),bit(s, 8),bit(k, 8),bit(k, 0))), | |
fb(bv2i(bit(s,33),bit(k,33),bit(s,25),bit(k,25),bit(s,17))), | |
fe(bv2i(bit(k,17),bit(s, 9),bit(k, 9),bit(k, 1))), | |
fd(bv2i(bit(s,34),bit(k,34),bit(s,26),bit(k,26),bit(s,18))), | |
fc(bv2i(bit(k,18),bit(s,10),bit(k,10),bit(s, 2),bit(k, 2))), | |
fb(bv2i(bit(s,35),bit(k,35),bit(s,27),bit(k,27),bit(s,19))), | |
fa(bv2i(bit(k,19),bit(s,11),bit(k,11),bit(s, 3),bit(k, 3))), | |
fd(bv2i(bit(s,36),bit(k,36),bit(s,28),bit(k,28),bit(s,20))), | |
fc(bv2i(bit(k,20),bit(s,12),bit(k,12),bit(s, 4),bit(k, 4))), | |
fb(bv2i(bit(s,37),bit(k,37),bit(s,29),bit(k,29),bit(s,21))), | |
fa(bv2i(bit(k,21),bit(s,13),bit(k,13),bit(s, 5),bit(k, 5))), | |
fd(bv2i(bit(s,38),bit(k,38),bit(s,30),bit(k,30),bit(s,22))), | |
fc(bv2i(bit(k,22),bit(s,14),bit(k,14),bit(s, 6),bit(k, 6))), | |
fb(bv2i(bit(s,39),bit(k,39),bit(s,31),bit(k,31),bit(s,23))), | |
fa(bv2i(bit(k,23),bit(s,15),bit(k,15),bit(s, 7),bit(k, 7))), | |
)[::-1] | |
def g(s,k): | |
fx=fn(s,k) | |
return ( | |
fg(bv2i(*fx[ :4])), | |
fg(bv2i(*fx[4:8])), | |
fg(bv2i(*fx[8:12])), | |
fg(bv2i(*fx[12:])) | |
)[::-1] | |
def f(k,s): | |
return h(bv2i(*g(s,k))) | |
def p1(x): | |
out=x&(0b10100101) | |
out|=bit(x,6)<<3 | |
out|=bit(x,4)<<1 | |
out|=bit(x,3)<<6 | |
out|=bit(x,1)<<4 | |
return out | |
def p2(x): | |
out=0 | |
for i in range(0,40,8): | |
byte=bit_slice(x,i+8,i) | |
out|=(p1(byte)<<i) | |
return out | |
def dst80_merge(keyl,keyr): | |
keyl = p2(keyl) | |
keyr = p2(keyr) | |
if bit(keyl,39)==1: keyl = 0x7fffffffff^keyl | |
if bit(keyr,39)==1: keyr = 0x7fffffffff^keyr | |
return (bit_slice(keyl,39,20)<<20)|bit_slice(keyr,39,20) | |
def lfsr_round(x): | |
return (x>>1)|((bit(x,0)^bit(x,2)^bit(x,19)^bit(x,21))<<39) | |
def dst80_round(keyl,keyr,s): | |
k=dst80_merge(keyl,keyr) | |
s=(s>>2)|((f(k,s)^(s&3))<<38) | |
keyr=lfsr_round(keyr) | |
keyl=lfsr_round(keyl) | |
return keyl,keyr,s | |
def dst80_rounds(keyl,keyr,s,nrounds): | |
for i in range(nrounds): | |
keyl,keyr,s=dst80_round(keyl,keyr,s) | |
return s | |
def dst80(keyl,keyr,challenge): | |
return dst80_rounds(keyl,keyr,challenge,200)&0xffffff | |
# --------------------------- | |
# test vectors | |
assert(dst80(0,0,0xC212345678)==0xceea8f) | |
assert(dst80(0xAAAAAAAAAA,0,0xC212345678)==0x28603a) | |
assert(dst80(0,0xAAAAAAAAAA,0xC212345678)==0x953d0a) | |
assert(dst80(0xAAAAAAAAAA,0xAAAAAAAAAA,0xC212345678)==0xc06085) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment