def SEQ(self, M, bitlen=None): pad = Nullpadding(3072) B = [ struct.unpack('>48Q', X) for X in pad.iterblocks(M, bitlen=bitlen) ] j = len(B) z = 0 d, keylen, L, r = self.size, self.keylen, self.L, self.rounds V = Bits(d, 12) // Bits(keylen, 8) // Bits(0, 16) // Bits( z, 4) // Bits(L, 8) // Bits(r, 12) // Bits(0, 4) C = Poly(0, 64, dim=16) W = Poly(Q, 64, dim=89) // Poly(self.K, 64) W.dim = 89 W[24] = V U = (self.L + 1) << 56 for i in range(j): if i == (j - 1): V[20:36] = pad.padcnt V[36:40] = Bits(1, 4) W[24] = V W[23] = U + i W[25:41] = C W[41:89] = B[i] C = self.f(W) h = concat(list(C)[::-1]) h.size = self.size return pack(h, '>L')
def initstate(self, salt=b'', pers=b'', keylen=0, **kargs): super(Blake2, self).initstate(0) self.padmethod = Nullpadding(self.blocksize) self.outlen = kargs.get('outlen', self.outlen) self.rounds = 12 if self.size > 256 else 10 l = self.wsize // 4 if salt is b'': salt = b'\0' * l if pers is b'': pers = b'\0' * l self.keylen = keylen assert 0 < self.outlen <= self.wsize assert self.keylen <= self.wsize self.treeinit(**kargs) self.paramblock(salt, pers)
def PAR(self,l,M,bitlen=None): pad = Nullpadding(4096) B = [struct.unpack('>64Q',X) for X in pad.iterblocks(M,bitlen=bitlen)] j = len(B) z = 1 if j==1 else 0 d,keylen,L,r = self.size,self.keylen,self.L,self.rounds V = Bits(d,12)//Bits(keylen,8)//Bits(0,16)//Bits(z,4)//Bits(L,8)//Bits(r,12)//Bits(0,4) C = [] W = Poly(Q,64)//Poly(self.K,64) W.dim = 89 W[24] = V for i in range(j): if i==(j-1): V[20:36]=pad.padcnt W[24] = V U = (l<<56)+i W[23] = U W[25:89] = B[i] C.append(self.f(W)) Ml = concat(C) return b''.join((pack(c,'>L') for c in Ml))
def initstate(self,salt=b'',pers=b'',keylen=0,**kargs): super(Blake2,self).initstate(0) self.padmethod = Nullpadding(self.blocksize) self.outlen = kargs.get('outlen',self.outlen) self.rounds = 12 if self.size>256 else 10 l = self.wsize//4 if salt is b'': salt = b'\0'*l if pers is b'': pers = b'\0'*l self.keylen=keylen assert 0<self.outlen<=self.wsize assert self.keylen<=self.wsize self.treeinit(**kargs) self.paramblock(salt,pers)
def SEQ(self,M,bitlen=None): pad = Nullpadding(3072) B = [struct.unpack('>48Q',X) for X in pad.iterblocks(M,bitlen=bitlen)] j = len(B) z = 0 d,keylen,L,r = self.size,self.keylen,self.L,self.rounds V = Bits(d,12)//Bits(keylen,8)//Bits(0,16)//Bits(z,4)//Bits(L,8)//Bits(r,12)//Bits(0,4) C = Poly(0,64,dim=16) W = Poly(Q,64,dim=89)//Poly(self.K,64) W.dim = 89 W[24] = V U = (self.L+1)<<56 for i in range(j): if i==(j-1): V[20:36]=pad.padcnt V[36:40]=Bits(1,4) W[24] = V W[23] = U+i W[25:41] = C W[41:89] = B[i] C = self.f(W) h = concat(list(C)[::-1]) h.size = self.size return pack(h,'>L')
def PAR(self, l, M, bitlen=None): pad = Nullpadding(4096) B = [ struct.unpack('>64Q', X) for X in pad.iterblocks(M, bitlen=bitlen) ] j = len(B) z = 1 if j == 1 else 0 d, keylen, L, r = self.size, self.keylen, self.L, self.rounds V = Bits(d, 12) // Bits(keylen, 8) // Bits(0, 16) // Bits( z, 4) // Bits(L, 8) // Bits(r, 12) // Bits(0, 4) C = [] W = Poly(Q, 64) // Poly(self.K, 64) W.dim = 89 W[24] = V for i in range(j): if i == (j - 1): V[20:36] = pad.padcnt W[24] = V U = (l << 56) + i W[23] = U W[25:89] = B[i] C.append(self.f(W)) Ml = concat(C) return b''.join((pack(c, '>L') for c in Ml))
class Blake2(Blake): def initstate(self, salt=b'', pers=b'', keylen=0, **kargs): super(Blake2, self).initstate(0) self.padmethod = Nullpadding(self.blocksize) self.outlen = kargs.get('outlen', self.outlen) self.rounds = 12 if self.size > 256 else 10 l = self.wsize // 4 if salt is b'': salt = b'\0' * l if pers is b'': pers = b'\0' * l self.keylen = keylen assert 0 < self.outlen <= self.wsize assert self.keylen <= self.wsize self.treeinit(**kargs) self.paramblock(salt, pers) def paramblock(self, salt, pers): P = pack( Poly([self.outlen, self.keylen, self.fanout, self.depth], size=8)) P += pack(self.leafl) P += pack(self.noffset) P += pack(Poly([self.ndepth, self.inner], size=8)) if self.size == 512: P += b'\0' * 14 P += salt + pers self.P = Poly(Bits(P, bitorder=1).split(self.wsize), self.wsize) self.H = self.IV ^ self.P def treeinit(self, fanout=1, depth=1, leafl=0, noffset=0, ndepth=0, inner=0, **kargs): self.fanout = fanout self.depth = depth self.leafl = Bits(leafl, 32) self.noffset = Bits(noffset, 64 if self.size == 512 else 48) self.ndepth = ndepth self.inner = inner def iterblocks(self, M, padding=False): g = self.padmethod.iterblocks(M, padding=padding) blk = next(g) while (blk): try: #forsee last block: nextblk = next(g) except StopIteration: # set f0 finalization flag (blk is last) self.f[0] = -1 nextblk = None # input words are now in little-endian: yield Bits(blk, bitorder=1).split(self.wsize) blk = nextblk def __call__(self, M, **kargs): self.initstate(**kargs) return self.update(M, padding=True) def update(self, M, padding=False): def G(W, r, i, v, ja, jb, jc, jd): ii = i + i p, q = sigma[r % 10][ii:ii + 2] xx = (32, 24, 16, 63) if self.size > 256 else (16, 12, 8, 7) a, b, c, d = (x for x in v[ja, jb, jc, jd]) a = a + b + W[p] d = ror(d ^ a, xx[0]) c = c + d b = ror(b ^ c, xx[1]) a = a + b + W[q] d = ror(d ^ a, xx[2]) c = c + d b = ror(b ^ c, xx[3]) v[ja, jb, jc, jd] = a, b, c, d # finalization flags f0,f1: self.f = Poly([0, 0], self.wsize) for W in self.iterblocks(M, padding=padding): v = Poly(0, self.wsize, dim=16) v[0:8] = self.H v[8:12] = self.IV[0:4] # counter of *bytes*, in little-endian t = Bits(self.padmethod.bitcnt // 8, 2 * self.wsize).split(self.wsize) v[12:14] = Poly(t, self.wsize) ^ self.IV[4:6] v[14:16] = self.f ^ self.IV[6:8] for r in range(self.rounds): G(W, r, 0, v, 0, 4, 8, 12) G(W, r, 1, v, 1, 5, 9, 13) G(W, r, 2, v, 2, 6, 10, 14) G(W, r, 3, v, 3, 7, 11, 15) G(W, r, 4, v, 0, 5, 10, 15) G(W, r, 5, v, 1, 6, 11, 12) G(W, r, 6, v, 2, 7, 8, 13) G(W, r, 7, v, 3, 4, 9, 14) self.H = self.H ^ (v[0:8] ^ v[8:16]) # output hash string in little endian: return b''.join([pack(h) for h in self.H])[:self.outlen]
class Blake2(Blake): def initstate(self,salt=b'',pers=b'',keylen=0,**kargs): super(Blake2,self).initstate(0) self.padmethod = Nullpadding(self.blocksize) self.outlen = kargs.get('outlen',self.outlen) self.rounds = 12 if self.size>256 else 10 l = self.wsize//4 if salt is b'': salt = b'\0'*l if pers is b'': pers = b'\0'*l self.keylen=keylen assert 0<self.outlen<=self.wsize assert self.keylen<=self.wsize self.treeinit(**kargs) self.paramblock(salt,pers) def paramblock(self,salt,pers): P = pack(Poly([self.outlen,self.keylen,self.fanout,self.depth],size=8)) P += pack(self.leafl) P += pack(self.noffset) P += pack(Poly([self.ndepth,self.inner],size=8)) if self.size==512: P += b'\0'*14 P += salt+pers self.P = Poly(Bits(P,bitorder=1).split(self.wsize),self.wsize) self.H = self.IV ^ self.P def treeinit(self,fanout=1,depth=1,leafl=0,noffset=0,ndepth=0,inner=0,**kargs): self.fanout = fanout self.depth = depth self.leafl = Bits(leafl,32) self.noffset = Bits(noffset,64 if self.size==512 else 48) self.ndepth = ndepth self.inner = inner def iterblocks(self,M,padding=False): g = self.padmethod.iterblocks(M,padding=padding) blk = next(g) while (blk): try: #forsee last block: nextblk = next(g) except StopIteration: # set f0 finalization flag (blk is last) self.f[0]= -1 nextblk = None # input words are now in little-endian: yield Bits(blk,bitorder=1).split(self.wsize) blk = nextblk def __call__(self,M,**kargs): self.initstate(**kargs) return self.update(M,padding=True) def update(self,M,padding=False): def G(W,r,i,v,ja,jb,jc,jd): ii = i+i p,q = sigma[r%10][ii:ii+2] xx = (32,24,16,63) if self.size>256 else (16,12,8,7) a,b,c,d = (x for x in v[ja,jb,jc,jd]) a = a+b+W[p] d = ror(d^a,xx[0]) c = c+d b = ror(b^c,xx[1]) a = a+b+W[q] d = ror(d^a,xx[2]) c = c+d b = ror(b^c,xx[3]) v[ja,jb,jc,jd] = a,b,c,d # finalization flags f0,f1: self.f = Poly([0,0],self.wsize) for W in self.iterblocks(M,padding=padding): v = Poly(0,self.wsize,dim=16) v[0:8] = self.H v[8:12] = self.IV[0:4] # counter of *bytes*, in little-endian t = Bits(self.padmethod.bitcnt//8,2*self.wsize).split(self.wsize) v[12:14] = Poly(t,self.wsize)^self.IV[4:6] v[14:16] = self.f^self.IV[6:8] for r in range(self.rounds): G(W,r,0,v,0,4,8,12) G(W,r,1,v,1,5,9,13) G(W,r,2,v,2,6,10,14) G(W,r,3,v,3,7,11,15) G(W,r,4,v,0,5,10,15) G(W,r,5,v,1,6,11,12) G(W,r,6,v,2,7,8,13) G(W,r,7,v,3,4,9,14) self.H = self.H^(v[0:8]^v[8:16]) # output hash string in little endian: return b''.join([pack(h) for h in self.H])[:self.outlen]