class BlindSignatureVerifier: def __init__(self, pubk: dict): self.p = pubk.get('p') self.q = pubk.get('q') self.g = pubk.get('g') self.y = pubk.get('y') self.h = pubk.get('h') self.z = pubk.get('z') self.group = IntegerGroupQ() self.group.setparam(p=self.p, q=self.q) def verify(self, signature, message): zeta = signature.get('zeta') zeta1 = signature.get('zeta1') rho = signature.get('rho') omega = signature.get('omega') sigma1 = signature.get('sigma1') sigma2 = signature.get('sigma2') delta = signature.get('delta') mu = signature.get('mu') tmp1 = (self.g ** rho) * (self.y ** omega) % self.p tmp2 = (self.g ** sigma1) * (zeta1 ** delta) % self.p tmp3 = (self.h ** sigma2) * ((zeta / zeta1) ** delta) % self.p tmp4 = (self.z ** mu) * (zeta ** delta) % self.p p1 = (omega + delta) % self.q p2 = integer(hash_int([zeta, zeta1, tmp1, tmp2, tmp3, tmp4, message])) % self.q return p1 == p2
class Room: def __init__(self, s, b = True): self.s = s self.group = IntegerGroupQ() if b and not self.s.get('p') is None and not self.s.get('q') is None: self.p = self.group.deserialize(fromBase64(self.s['p'])) self.q = self.group.deserialize(fromBase64(self.s['q'])) self.group.setparam(self.p, self.q) def state(self, s): self.set('state', s) self.save() def check(self, v): try: return self.get('state') == v except: print(v, self.s.get('state')) return False def get(self, n, f = None): if f is None: f = lambda x: self.group.deserialize(x) if type(x) == bytes else x return map( f, fromBase64(self.s.get(n)) ) def set(self, n, v, f = None): if f is None: f = lambda x: self.group.serialize(x) if type(x) == integer else x self.s[n] = toBase64( map(f, v) ) def save(self): self.s.save() def clear(self): self.s.clear() self.s.save()
class UserBlindSignature(BlindSigner): """ This class represents the entity who wishes to have a certain message blindly signed. """ def __init__(self, input_=None): if input_ is not None: self.p = input_.get('p') self.q = input_.get('q') self.g = input_.get('g') self.y = input_.get('y') self.h = input_.get('h') self.z = input_.get('z') self.group = IntegerGroupQ() self.group.setparam(p=self.p, q=self.q) self.db = input_.get('db') if self.db is None: self.db = {} def __store__(self, *args): for i in args: if isinstance(i, tuple): self.db[i[0]] = i[1] return None def __get__(self, keys, _type=tuple): if not type(keys) == list: return if _type == tuple: ret = [] else: ret = {} # get the data for i in keys: if _type == tuple: ret.append(self.db[i]) else: # dict ret[i] = self.db[i] # return data if _type == tuple: return tuple(ret) return ret def challenge_response(self, input, message): rnd = input.get('rnd') a = input.get('a') b1 = input.get('b1') b2 = input.get('b2') msg = integer(Conversion.OS2IP(SHA1(Conversion.IP2OS(rnd)))) z1 = (msg ** ((self.p - 1) / self.q)) % self.p gamma = self.group.random() tau = self.group.random() t1 = self.group.random() t2 = self.group.random() t3 = self.group.random() t4 = self.group.random() t5 = self.group.random() zeta = self.z ** gamma zeta1 = z1 ** gamma zeta2 = zeta / zeta1 alpha = a * (self.g ** t1) * (self.y ** t2) % self.p beta1 = (b1 ** gamma) * (self.g ** t3) * (zeta1 ** t4) % self.p beta2 = (b2 ** gamma) * (self.h ** t5) * (zeta2 ** t4) % self.p eta = self.z ** tau epsilon = integer(hash_int([zeta, zeta1, alpha, beta1, beta2, eta, message])) % self.q e = (epsilon - t2 - t4) % self.q self.__store__(self, ('z1', z1), ('zeta', zeta), ('zeta1', zeta1)) self.__store__(self, ('zeta2', zeta2), ('alpha', alpha), ('beta1', beta1), ('beta2', beta2)) self.__store__(self, ('t1', t1), ('t2', t2), ('t3', t3), ('t4', t4), ('t5', t5)) self.__store__(self, ('gamma', gamma), ('tau', tau), ('eta', eta)) return {'e': e} def gen_signature(self, proofs: dict) -> dict: r = proofs.get('r') c = proofs.get('c') d = proofs.get('d') s1 = proofs.get('s1') s2 = proofs.get('s2') (zeta, zeta1, z, z1) = self.__get__(['zeta', 'zeta1', 'zeta2', 'z1']) (t1, t2, t3, t4, t5) = self.__get__(['t1', 't2', 't3', 't4', 't5']) (gamma, tau, eta) = self.__get__(['gamma', 'tau', 'eta']) rho = (r + t1) % self.q omega = (c + t2) % self.q sigma1 = ((gamma * s1) + t3) % self.q sigma2 = ((gamma * s2) + t5) % self.q delta = (d + t4) % self.q mu = (tau - (delta * gamma)) % self.q return {'zeta': zeta, 'zeta1': zeta1, 'rho': rho, 'omega': omega, 'sigma1': sigma1, 'sigma2': sigma2, 'delta': delta, 'mu': mu}