dss_sig_value: Pure python conversion of (r, s) to byte stream
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 7a0b9e7..7b3ffbc 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -27,11 +27,11 @@
 import cryptography_vectors
 
 from .utils import (
-    check_backend_support, check_for_iface, load_cryptrec_vectors,
-    load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors,
-    load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors,
-    load_hash_vectors, load_nist_vectors, load_pkcs1_vectors,
-    load_rsa_nist_vectors, load_vectors_from_file,
+    check_backend_support, check_for_iface, dss_sig_value,
+    load_cryptrec_vectors, load_fips_dsa_key_pair_vectors,
+    load_fips_dsa_sig_vectors, load_fips_ecdsa_key_pair_vectors,
+    load_fips_ecdsa_signing_vectors, load_hash_vectors, load_nist_vectors,
+    load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file,
     raises_unsupported_algorithm, select_backends
 )
 
@@ -125,6 +125,32 @@
         check_backend_support(item)
 
 
+def test_dss_sig_value():
+    sig = dss_sig_value(1, 1)
+    assert sig == b"0\x06\x02\x01\x01\x02\x01\x01"
+
+    sig2 = dss_sig_value(1037234182290683143945502320610861668562885151617,
+                         559776156650501990899426031439030258256861634312)
+    assert sig2 == (
+        b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b'
+        b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08'
+    )
+
+    sig3 = dss_sig_value(0, 0)
+    assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00"
+
+
+def test_dss_sig_value_negative():
+    with pytest.raises(ValueError):
+        dss_sig_value(-1, 1)
+
+    with pytest.raises(ValueError):
+        dss_sig_value(1, -1)
+
+    with pytest.raises(ValueError):
+        dss_sig_value(-1, -1)
+
+
 def test_load_nist_vectors():
     vector_data = textwrap.dedent("""
     # CAVS 11.1
diff --git a/tests/utils.py b/tests/utils.py
index 60b6f5a..d856513 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -80,6 +80,33 @@
     assert exc_info.value._reason is reason
 
 
+def _int_to_asn1_int(i):
+    """
+    Used by dss_sig_value to convert python integers to ASN.1 integer bytes.
+    """
+    if i == 0:
+        return b'\x02\x01\x00'
+    if i < 0:
+        raise ValueError("This only supports positive integers right now.")
+    result = []
+    while i:
+        result.append(six.int2byte(i & 0xFF))
+        i >>= 8
+    # ASN.1 integers are stored big endian two's complement, so add a byte if
+    # the ordinal value of the last byte is over 0x7f.
+    if ord(result[-1]) > 127:
+        result.append(b"\x00")
+    result.reverse()
+    packed = b''.join(result)
+    return b"\x02" + chr(len(packed)).encode("ascii") + packed
+
+
+def dss_sig_value(r, s):
+    combined = _int_to_asn1_int(r) + _int_to_asn1_int(s)
+    sig = b"0" + chr(len(combined)).encode("ascii") + combined
+    return sig
+
+
 def load_vectors_from_file(filename, loader):
     with cryptography_vectors.open_vector_file(filename) as vector_file:
         return loader(vector_file)