Example #1
0
    def verify(self, message, signature):
        """Verify a signature."""
        # Unpack the salt and the short polynomial s1
        salt = signature[:SALT_LEN]
        enc_s = signature[SALT_LEN:]
        s1 = decompress(enc_s, self.sig_bytelen - SALT_LEN, self.n)

        # Check that the encoding is valid
        if (s1 is False):
            print("Invalid encoding")
            return False

        # Compute s0 and normalize its coefficients in (-q/2, q/2]
        hashed = self.hash_to_point(message, salt)
        s0 = sub_zq(hashed, mul_zq(s1, self.h))
        s0 = [(coef + (q >> 1)) % q - (q >> 1) for coef in s0]

        # Check that the (s0, s1) is short
        norm_sign = sum(coef**2 for coef in s0)
        norm_sign += sum(coef**2 for coef in s1)
        if norm_sign > self.signature_bound:
            print("Squared norm of signature is too large:", norm_sign)
            return False

        # If all checks are passed, accept
        return True
Example #2
0
def test_covariance(d, m, q, iterations=100):
    """
    Compute the covariance matrix of the signatures distribution.

    For an isotropic Gaussian, the covariance matrix is
    proportional to the identity matrix.
    """
    sk = SecretKey(d, m, q)
    dim = (m + 1) * d
    liste_sig = []
    mean = [0] * dim
    Cov = [[0 for _ in range(dim)] for _ in range(dim)]
    for i in range(iterations):
        message = "0"
        r, t = sk.sign(message)
        s = decompress(t, sk.d, sk.rate)
        s = sum([elt for elt in s], [])
        mean = add(mean, s)
        liste_sig += [s]
    # print("mean = {mean}".format(mean=mean))
    for s in liste_sig:
        s = [iterations * elt for elt in s]
        s = [(s[i] - mean[i]) for i in range(dim)]
        M = make_matrix(s)
        for i in range(dim):
            Cov[i] = add(Cov[i], M[i])
    # We normalize only at the end to work with integers as long as possible
    for i in range(dim):
        for j in range(dim):
            Cov[i][j] /= (iterations**3)
            Cov[i][j] = int(round(Cov[i][j]))
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 verify(self, message, signature):
        """
        Verify a signature.

        Input:
        self        The private key
        message     The message to sign
        signature   The signature (r, s)

        Output:
        True        If (s * A == H(r||message)) and (s is short)
        False       Otherwise
        """
        A = self.A
        q = self.q
        d = self.d
        m = self.m
        r, t = signature
        s = decompress(t, self.d, self.rate)
        # The message is hashed to a point of Z_q[x] / (x ** d + 1)
        hashed = self.hash_to_point(message, r)
        # One compute result = s * A
        result = [0] * d
        for i in range(m + 1):
            result = add_zq(result, mul_zq(s[i], A[i], q), q)
        # Check that the hashed point == result
        if any(result[i] != hashed[i] for i in range(d)):
            print("The signature does not correspond to the hash!")
            return False
        # Check that the norm is small
        norm_sign = sum(sum(elt**2 for elt in part) for part in s)
        if norm_sign > self.signature_bound:
            print("The squared norm of the signature is too big:", norm_sign)
            return False
        # If the two checks passed, accept
        return True