def _status_signature_state(state, status: CertificateStatusResponse) -> None: """Collect signature state over a status.""" CertificateVerifier._certificate_hash_signature_state(state, status.certificate) if status.status == CertificateStatus.UNKNOWN: crypto_sign_ed25519ph_update(state, bytes([0])) elif status.status == CertificateStatus.VALID: crypto_sign_ed25519ph_update(state, bytes([1])) elif status.status == CertificateStatus.INVALID: crypto_sign_ed25519ph_update(state, bytes([2])) else: raise Exception(f"invalid certificate status {status.status}") crypto_sign_ed25519ph_update(state, struct.pack(">Q", status.valid_from)) crypto_sign_ed25519ph_update(state, struct.pack(">I", status.valid_length)) CertificateVerifier._certificate_signature_state(state, status.status_certificate, True)
def test_sign_ed25519ph_rfc8032(): # sk, pk, msg, exp_sig # taken from RFC 8032 section 7.3. Test Vectors for Ed25519ph sk = unhexlify(b"833fe62409237b9d62ec77587520911e" b"9a759cec1d19755b7da901b96dca3d42") pk = unhexlify(b"ec172b93ad5e563bf4932c70e1245034" b"c35467ef2efd4d64ebf819683467e2bf") msg = b"abc" exp_sig = unhexlify(b"98a70222f0b8121aa9d30f813d683f80" b"9e462b469c7ff87639499bb94e6dae41" b"31f85042463c2a355a2003d062adf5aa" b"a10b8c61e636062aaad11c2a26083406") c_sk = sk + pk edph = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph, msg) sig = c.crypto_sign_ed25519ph_final_create(edph, c_sk) assert sig == exp_sig edph_v = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_v, msg) assert c.crypto_sign_ed25519ph_final_verify(edph_v, exp_sig, pk) is True c.crypto_sign_ed25519ph_update(edph_v, msg) with pytest.raises(BadSignatureError): c.crypto_sign_ed25519ph_final_verify(edph_v, exp_sig, pk)
def test_sign_ed25519ph_rfc8032(): # sk, pk, msg, exp_sig # taken from RFC 8032 section 7.3. Test Vectors for Ed25519ph sk = unhexlify(b'833fe62409237b9d62ec77587520911e' b'9a759cec1d19755b7da901b96dca3d42') pk = unhexlify(b'ec172b93ad5e563bf4932c70e1245034' b'c35467ef2efd4d64ebf819683467e2bf') msg = b'abc' exp_sig = unhexlify(b'98a70222f0b8121aa9d30f813d683f80' b'9e462b469c7ff87639499bb94e6dae41' b'31f85042463c2a355a2003d062adf5aa' b'a10b8c61e636062aaad11c2a26083406') c_sk = sk + pk edph = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph, msg) sig = c.crypto_sign_ed25519ph_final_create(edph, c_sk) assert sig == exp_sig edph_v = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_v, msg) assert c.crypto_sign_ed25519ph_final_verify(edph_v, exp_sig, pk) is True c.crypto_sign_ed25519ph_update(edph_v, msg) with pytest.raises(BadSignatureError): c.crypto_sign_ed25519ph_final_verify(edph_v, exp_sig, pk)
def test_sign_ed25519ph_libsodium(): # _hsk, _hpk, hmsg, _hsig, _hsigmsg = ed25519_known_answers()[-1] msg = unhexlify(hmsg) seed = unhexlify(b"421151a459faeade3d247115f94aedae" b"42318124095afabe4d1451a559faedee") pk, sk = c.crypto_sign_seed_keypair(seed) exp_sig = unhexlify(b"10c5411e40bd10170fb890d4dfdb6d33" b"8c8cb11d2764a216ee54df10977dcdef" b"d8ff755b1eeb3f16fce80e40e7aafc99" b"083dbff43d5031baf04157b48423960d") edph = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph, msg) sig = c.crypto_sign_ed25519ph_final_create(edph, sk) assert sig == exp_sig edph_incr = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_incr, b"") c.crypto_sign_ed25519ph_update(edph_incr, msg[0:len(msg) // 2]) c.crypto_sign_ed25519ph_update(edph_incr, msg[len(msg) // 2:]) assert c.crypto_sign_ed25519ph_final_verify(edph_incr, exp_sig, pk) is True with pytest.raises(BadSignatureError): wrng_sig = flip_byte(exp_sig, 0) c.crypto_sign_ed25519ph_final_verify(edph_incr, wrng_sig, pk) with pytest.raises(BadSignatureError): wrng_mesg = flip_byte(msg, 1022) edph_wrng = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_wrng, wrng_mesg) c.crypto_sign_ed25519ph_final_verify(edph_wrng, exp_sig, pk)
def test_sign_ed25519ph_libsodium(): # _hsk, _hpk, hmsg, _hsig, _hsigmsg = ed25519_known_answers()[-1] msg = unhexlify(hmsg) seed = unhexlify(b'421151a459faeade3d247115f94aedae' b'42318124095afabe4d1451a559faedee') pk, sk = c.crypto_sign_seed_keypair(seed) exp_sig = unhexlify(b'10c5411e40bd10170fb890d4dfdb6d33' b'8c8cb11d2764a216ee54df10977dcdef' b'd8ff755b1eeb3f16fce80e40e7aafc99' b'083dbff43d5031baf04157b48423960d') edph = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph, msg) sig = c.crypto_sign_ed25519ph_final_create(edph, sk) assert sig == exp_sig edph_incr = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_incr, b'') c.crypto_sign_ed25519ph_update(edph_incr, msg[0:len(msg) // 2]) c.crypto_sign_ed25519ph_update(edph_incr, msg[len(msg) // 2:]) assert c.crypto_sign_ed25519ph_final_verify(edph_incr, exp_sig, pk) is True with pytest.raises(BadSignatureError): wrng_sig = flip_byte(exp_sig, 0) c.crypto_sign_ed25519ph_final_verify(edph_incr, wrng_sig, pk) with pytest.raises(BadSignatureError): wrng_mesg = flip_byte(msg, 1022) edph_wrng = c.crypto_sign_ed25519ph_state() c.crypto_sign_ed25519ph_update(edph_wrng, wrng_mesg) c.crypto_sign_ed25519ph_final_verify(edph_wrng, exp_sig, pk)
def _certificate_hash_signature_state(state, cert: CertificateHash) -> None: """Collect signature state over a certificate hash.""" crypto_sign_ed25519ph_update(state, cert.value) if cert.algorithm == HashAlgorithm.SHA256: crypto_sign_ed25519ph_update(state, bytes([1])) elif cert.algorithm == HashAlgorithm.SHA512: crypto_sign_ed25519ph_update(state, bytes([2])) else: raise Exception(f"unsupported hash algorithm {cert.algorithm}")
def _certificate_signature_state(state, cert: Certificate, include_signature: bool) -> None: """Collect signature state over a certificate.""" for s in cert.subjects: crypto_sign_ed25519ph_update(state, s.encode("UTF-8")) crypto_sign_ed25519ph_update(state, struct.pack(">Q", cert.valid_from)) crypto_sign_ed25519ph_update(state, struct.pack(">I", cert.valid_length)) for u in cert.usages: if u == CertificateUsage.CERTIFICATE_SIGNING: crypto_sign_ed25519ph_update(state, bytes([0])) elif u == CertificateUsage.CLIENT_AUTHENTICATION: crypto_sign_ed25519ph_update(state, bytes([1])) elif u == CertificateUsage.SERVER_AUTHENTICATION: crypto_sign_ed25519ph_update(state, bytes([2])) elif u == CertificateUsage.STATUS_SIGNING: crypto_sign_ed25519ph_update(state, bytes([3])) else: raise Exception(f"invalid certificate usage {u}") crypto_sign_ed25519ph_update(state, cert.encryption_public_key) crypto_sign_ed25519ph_update(state, cert.signing_public_key) if cert.HasField("issuer"): crypto_sign_ed25519ph_update(state, cert.issuer.value) if cert.issuer.algorithm == HashAlgorithm.SHA256: crypto_sign_ed25519ph_update(state, bytes([1])) elif cert.issuer.algorithm == HashAlgorithm.SHA512: crypto_sign_ed25519ph_update(state, bytes([2])) else: raise Exception(f"unsupported hash algorithm {cert.issuer.algorithm}") if include_signature: crypto_sign_ed25519ph_update(state, cert.issuer_signature)