def JW_commit(x, m=15, n=20, symsize=8): """*Juels Wattenberg* based function to make a fuzzy commitment m,n,symsize initializes Reed-Solomon-Code with :math:`RS(q=2^{symsize},m,n)`. * m -- Messages * n -- Codewords * Initializes Set of Codewords C :param x: Input key x. :type x: list :param m: Parameter for Reed-Solomon-Code. :param n: Parameter for Reed-Solomon-Code. :param symsize: Parameter for Reed-Solomon-Code. :return: hash -- Hash of c. :return: delta -- Difference between x and c. :return: c -- Randomly generated codeword :math:`c \in C`. """ # Reed Solomon Codeword Set C with RS(2**symsize, m, n) # m Messages # n Codewords # size -> 2**symsize -1 C = IntegerCodec(n, m, symsize) # generate random codeword c: # randomize c_pre c_pre = safe_random(m, symsize=symsize) # map c_pre to codeword c to get a real codeword in C c = scipy.array(C.encode(c_pre)) # now size n! log.debug('random codeword c in C:\n'+str(c)) log.debug('length of codeword c: '+str(len(c))) # calculate delta delta = (x-c) % (2**symsize) # generate SHA-256 Hash Hash = SHA256.new("".join(c.astype(str))) hash = Hash.hexdigest().split() return hash, delta, c
def __init__(self, symbolSize, messageBytes, rsExpansionFactor): logging.info('RS EXPANSION FACTOR %s' % rsExpansionFactor) assert rsExpansionFactor > 1 self.width = symbolSize self.messageSymbols = int( math.ceil(float(messageBytes) * 8 / symbolSize)) self.encodedSize = int( math.ceil(float(self.messageSymbols) * rsExpansionFactor)) self.c = IntegerCodec(self.encodedSize, self.messageSymbols, symsize=symbolSize) self.extraSymbols = self.encodedSize - self.messageSymbols self.n = 3 self.messageBytes = int(messageBytes) self.encodedBits = math.ceil( float(self.encodedSize) * self.width * self.n) logging.info('ENCODED BITS %s' % self.encodedBits)
def JW_decommit(hash, delta, x2, m=15, n=20, symsize=8): """Juels Wattenberg function to decommit a fuzzy commitment m,n,symsize initializes Reed-Solomon-Code with :math:`RS(q=2^{symsize},m,n)`. * m -- Messages * n -- Codewords * Initializes Set of Codewords C :param hash: Hash of c from Alice. :param delta: Difference from Alice. :param x2: Own input key x2. Slightly different from Alice x. :param m: Parameter for Reed-Solomon-Code. :param n: Parameter for Reed-Solomon-Code. :param symsize: Parameter for Reed-Solomon-Code. :return: c2 -- Decommited c2 :return: corrections -- List of corrections made by Reed-Solomon :raise: RuntimeError """ # calculate difference x-delta diff = (x2-delta) % (2**symsize) #log.debug('Difference (codeword-delta):\n'+str(diff)) # Reed Solomon Codeword Set C with RS(2**symsize, m, n) # m Messages # n Codewords # size -> 2**symsize -1 C = IntegerCodec(n, m, symsize=symsize) # map diff to nearest codeword c_pre try: c_pre, corrections = C.decode(diff) except Exception, err: log.error('%s' % str(err)) raise RuntimeError("Error in Decode of Reedsolomon Library")
class LayeredEncoder(object): def __init__(self, symbolSize, messageBytes, rsExpansionFactor): logging.info('RS EXPANSION FACTOR %s' % rsExpansionFactor) assert rsExpansionFactor > 1 self.width = symbolSize self.messageSymbols = int( math.ceil(float(messageBytes) * 8 / symbolSize)) self.encodedSize = int( math.ceil(float(self.messageSymbols) * rsExpansionFactor)) self.c = IntegerCodec(self.encodedSize, self.messageSymbols, symsize=symbolSize) self.extraSymbols = self.encodedSize - self.messageSymbols self.n = 3 self.messageBytes = int(messageBytes) self.encodedBits = math.ceil( float(self.encodedSize) * self.width * self.n) logging.info('ENCODED BITS %s' % self.encodedBits) def encode(self, data): bits = list(toBitSequence(data)) ints = map(toInt, partition(bits, self.width)) encoded = [] encodedInts = self.c.encode(ints) for encodedInt in encodedInts: encoded.extend(toBits(encodedInt, self.width) * self.n) #logging.info('Encoded %s' % encodedInts) #logging.info('Encoded %s %s' % (len(encoded), encoded)) return encoded def decode(self, signals): signals = map(signum, signals) #logging.info('SIGNALS %s', signals) droppedSymbols = [] encodedInts = [] decoded = [] errors = 0 chunks = partition(signals, self.width) for chunkList in partition(chunks, self.n): #def prettyInt(x): # if x == -1: return 'X' # else: return '-' # #crap = [''.join(map(prettyInt, c)) for c in chunkList] #logging.info("%s.." % ('\n'.join(crap)) ) counts = [sum(b) for b in zip(*chunkList)] #print counts #errors += sum([ self.n - abs(c) for c in counts ]) / 2 bits = map(signum, counts) encodedInts.append(toInt(bits)) # index = 0 # chunks = partition(signals, self.width) # assert self.n == 3 # for chunkList in partition(chunks, self.n): # votes = {} # ints = map(toInt, chunkList) # winner = None # for vote in ints: # if votes.has_key(vote): # winner = vote # break # votes[vote] = True # # if winner == None: # if len(droppedSymbols) < self.extraSymbols: # droppedSymbols.append(index) # else: # logging.info('!!!!!!!!Too many botched symbols %s' % droppedSymbols) # # raise DecodeException() # encodedInts.append(0) # else: # encodedInts.append(winner) # # index += 1 # try: #logging.info('----> Decoding %s' % [len(encodedInts), encodedInts, droppedSymbols]) decodedInts = self.c.decode(encodedInts, droppedSymbols)[0] except UncorrectableError, e: raise DecodeException() decodedBits = [] for decodedInt in decodedInts: decodedBits.extend(toBits(decodedInt, self.width)) return toByteSequence(decodedBits[:self.messageBytes * 8])