Example #1
0
    def sign(self, message, salt=None, verbose=False):
        """
        Sign a message. Needs hash randomization to be secure.

        Input:
        self        The private key
        message     The message to sign
        salt        The hashing salt (optional)
        verbose     If this flag is set, the algorithm notifies each time it restarts

        Output:
        r, s        A signature of the message:
                    - s * A = H(r||message)
                    - s is short
        """
        # If no salt is provided, one is generated randomly
        if salt is None:
            salt = randint(0, (1 << 320) - 1)
        # The message is hashed into a point of Z_q[x] / (x ** d + 1)
        r = ""
        for i in range(320 // 8):
            r += chr((salt >> (8 * i)) & 0xff)
        hashed = self.hash_to_point(message, r)
        # A short pre-image of this point is determined
        while (1):
            s = self.sample_preimage_fft(hashed)
            # The norm of the signature is checked
            norm_sign = sum(sum(elt**2 for elt in part) for part in s)
            if norm_sign < self.signature_bound:
                return r, compress(s, rate=self.rate)
            elif verbose is True:
                print("redo")
Example #2
0
    def sign(self, message, randombytes=urandom):
        """
        Sign a message. The message MUST be a byte string or byte array.
        Optionally, one can select the source of (pseudo-)randomness used
        (default: urandom).
        """
        int_header = 0x30 + logn[self.n]
        header = int_header.to_bytes(1, "little")

        salt = randombytes(SALT_LEN)
        hashed = self.hash_to_point(message, salt)

        # We repeat the signing procedure until we find a signature that is
        # short enough (both the Euclidean norm and the bytelength)
        while (1):
            if (randombytes == urandom):
                s = self.sample_preimage(hashed)
            else:
                seed = randombytes(SEED_LEN)
                s = self.sample_preimage(hashed, seed=seed)
            norm_sign = sum(coef**2 for coef in s[0])
            norm_sign += sum(coef**2 for coef in s[1])
            # Check the Euclidean norm
            if norm_sign <= self.signature_bound:
                enc_s = compress(s[1], self.sig_bytelen - HEAD_LEN - SALT_LEN)
                # Check that the encoding is valid (sometimes it fails)
                if (enc_s is not False):
                    return header + salt + enc_s
Example #3
0
def test_compress(d, q, iterations):
    """Test compression and decompression."""
    sigma = 1.5 * sqrt(q)
    for i in range(iterations):
        initial = [[int(round(gauss(0, sigma))) for coef in range(d)]]
        for rate in range(6, 9):
            compressed = compress(initial, rate=rate)
            decompressed = decompress(compressed, degree=d, rate=rate)
            if decompressed != initial:
                return False
    return True
Example #4
0
def test_compress(n, iterations):
	"""Test compression and decompression."""
	sigma = 1.5 * sqrt(q)
	for i in range(iterations):
		initial = [int(round(gauss(0, sigma))) for coef in range(n)]
		compressed = compress(initial)
		decompressed = decompress(compressed)
		# print compressed
		if decompressed != initial:
			return False
	return True
Example #5
0
def test_compress(n, iterations):
    """Test compression and decompression."""
    try:
        sigma = 1.5 * sqrt(q)
        slen = Params[n]["sig_bytelen"] - SALT_LEN
    except KeyError:
        return True
    for i in range(iterations):
        while(1):
            initial = [int(round(gauss(0, sigma))) for coef in range(n)]
            compressed = compress(initial, slen)
            if compressed is not False:
                break
        decompressed = decompress(compressed, slen, n)
        if decompressed != initial:
            return False
    return True
Example #6
0
 def sign(self, message):
     """
     Sign a message. The message MUST be a byte string or byte array.
     """
     salt = randombytes(SALT_LEN)
     hashed = self.hash_to_point(message, salt)
     # We repeat the signing procedure until we find a signature that is
     # short enough (both the Euclidean norm and the bytelength)
     while (1):
         s = self.sample_preimage(hashed)
         norm_sign = sum(coef**2 for coef in s[0])
         norm_sign += sum(coef**2 for coef in s[1])
         # Check the Euclidean norm
         if norm_sign < self.signature_bound:
             enc_s = compress(s[1], self.sig_bytelen - SALT_LEN)
             # Check that the encoding is valid (sometimes it fails)
             if (enc_s is not False):
                 return salt + enc_s