--  w3c ECDSA P256 signature vector verification. Specification source: https://www.w3.org/TR/vc-di-ecdsa/
P256 = require('es256')

function O_from_multibase58(mut58_str)
    -- Remove the base 58 encoding prefix character from the string
    local prefix = mut58_str:sub(1, 1)
    assert(prefix == 'z', 'Error, multibase conversion not valid, bad multibase58 value')
    local unprefixed_str = mut58_str:sub(2)
    return O.from_base58(unprefixed_str)
end

-- return hex compressed pk starting from a ecdsa multikey (designed only to work with ecdsa P256, no other cases considered)
function mulikey_to_hex(str)
    -- remove multibase58 encoding
    local O_multikey = O_from_multibase58(str)

    -- Remove the two-byte prefix 0x8024 character of ecdsa compressed public key from the string
    local hex_multikey = O.to_hex(O_multikey)
    local prefix = hex_multikey:sub(1, 4)
    assert(prefix == '8024' or prefix == '8626', 'Error. multikey convertion function called on a non ecdsa key')
    local compressed_pk = hex_multikey:sub(5)

    return compressed_pk
end

function controls(vector_m1, vector_m2, vector_h1, vector_h2, vector_multikey_pk, vector_multikey_sk, vector_m, vector_sg)
    print("Run test to verify signature and public key of w3c ecdsa-vc")
    -- multibase and multikey vectors conversions
    local vector_pk = O.from_hex(mulikey_to_hex(vector_multikey_pk)) -- this variable represent the ecdsa pk in compressed version
    local vector_sk = O.from_hex(mulikey_to_hex(vector_multikey_sk))

    -- [0] test if zenroom does verify the test vector signature
    assert(P256.verify(vector_pk, vector_m, vector_sg), "error in the ECDSA verification function; it is unable to validate the test vector.")

    -- [1] test hash correctness 
    local h1 = O.to_hex(sha256(vector_m1))
    assert(vector_h1 == h1, "hash and vector hash of Canonical Proof Options Document doesn't match")

    local h2 = O.to_hex(sha256(vector_m2))
    assert(vector_h2 == h2, "hash and vector hash of Canonical Credential without Proof doesn't match")

    -- [2] test the possibility to produce via zenroom a valid ecdsa-vc following the documentation procedure
    -- [2] test if public key vector does verify the signature produced by zenroom
    local m = O.from_hex(h1 .. h2)
    assert(vector_m == m, "the message produced to be signed does not match the test vector message")
    local sg = P256.sign(vector_sk, m)
    assert(P256.verify(vector_pk, vector_m, sg), "ecdsa verify failed, incorrect signature")

    -- [3] test if public key generated by zenroom does verify the test vector signature
    pk = P256.pubgen(vector_sk)
    assert(P256.verify(pk, vector_m, vector_sg), "ecdsa verify failed, incorrect public key")

    -- [4] test if zenroom produced pk when compressed matches w3c vector compressed pk
    local compressed_pk = P256.compress_public_key(pk) -- O.to_hex(compress_ecdsa_pk(pk))
    assert(vector_pk == compressed_pk, "ECDSA zenroom compressed pk does not match the test w3c vector")

    -- [5] test if zenroom produced expansion of vector_pk matches full pk
    local x, y = P256.pubxy(vector_pk)
    assert(x .. y == pk, "ECDSA zenroom pk does not match the uncompressed pk of w3c test vector")
end

-- vector: A.1 Representation: ecdsa-rdfc-2019, with curve P-256
local vector_m2_CanonicalCredential = O.from_str(
    [[<did:example:abcdefgh> <https://www.w3.org/ns/credentials/examples#alumniOf> "The School of Examples" .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/ns/credentials/examples#AlumniCredential> .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/description> "A minimum viable example of an Alumni Credential." .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/name> "Alumni Credential" .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#credentialSubject> <did:example:abcdefgh> .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#issuer> <https://vc.example/issuers/5678> .
<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#validFrom> "2023-01-01T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
]])
local vector_m1_CanonicalProofOptions = O.from_str(
    [[_:c14n0 <http://purl.org/dc/terms/created> "2023-02-24T23:36:38Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#DataIntegrityProof> .
_:c14n0 <https://w3id.org/security#cryptosuite> "ecdsa-rdfc-2019"^^<https://w3id.org/security#cryptosuiteString> .
_:c14n0 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> .
_:c14n0 <https://w3id.org/security#verificationMethod> <did:key:zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP#zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP> .
]])
local vector_h2 = '517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017'
local vector_h1 = '3a8a522f689025727fb9d1f0fa99a618da023e8494ac74f51015d009d35abc2e'
local vector_multikey_pk = 'zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP'
local vector_multikey_sk = 'z42twTcNeSYcnqg1FLuSFs2bsGH3ZqbRHFmvS9XMsYhjxvHN'
local vector_sg = O.from_hex('1cb4290918ffb04a55ff7ae1e55e316a9990fda8eec67325eac7fcbf2ddf9dd2b06716a657e72b284c9604df3a172ecbf06a1a475b49ac807b1d9162df855636')
local vector_m= O.from_hex('3a8a522f689025727fb9d1f0fa99a618da023e8494ac74f51015d009d35abc2e517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017')

controls(vector_m1_CanonicalProofOptions, vector_m2_CanonicalCredential, vector_h1, vector_h2, vector_multikey_pk,
    vector_multikey_sk, vector_m, vector_sg)

-- vector: A.2 Enhanced Example for Representation: ecdsa-rdfc-2019, with curve P-256
vector_m2_CanonicalCredential = O.from_str(
    [[<did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76> <https://schema.org/image> <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgUPr/HwADaAIhG61j/AAAAABJRU5ErkJggg==> .
_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmploymentAuthorizationDocumentCredential> .
_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
_:c14n0 <https://schema.org/description> "Example Employment Authorization Document." .
_:c14n0 <https://schema.org/name> "Employment Authorization Document" .
_:c14n0 <https://www.w3.org/2018/credentials#credentialSubject> _:c14n1 .
_:c14n0 <https://www.w3.org/2018/credentials#issuer> <did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76> .
_:c14n0 <https://www.w3.org/2018/credentials#validFrom> "2019-12-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n0 <https://www.w3.org/2018/credentials#validUntil> "2029-12-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://schema.org/Person> .
_:c14n1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmployablePerson> .
_:c14n1 <https://schema.org/additionalName> "JACOB" .
_:c14n1 <https://schema.org/birthDate> "1999-07-17"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n1 <https://schema.org/familyName> "SMITH" .
_:c14n1 <https://schema.org/gender> "Male" .
_:c14n1 <https://schema.org/givenName> "JOHN" .
_:c14n1 <https://schema.org/image> <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2Ng+M/wHwAEAQH/7yMK/gAAAABJRU5ErkJggg==> .
_:c14n1 <https://w3id.org/citizenship#birthCountry> "Bahamas" .
_:c14n1 <https://w3id.org/citizenship#employmentAuthorizationDocument> _:c14n2 .
_:c14n1 <https://w3id.org/citizenship#residentSince> "2015-01-01"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmploymentAuthorizationDocument> .
_:c14n2 <https://schema.org/identifier> "83627465" .
_:c14n2 <https://w3id.org/citizenship#lprCategory> "C09" .
_:c14n2 <https://w3id.org/citizenship#lprNumber> "999-999-999" .
]])
vector_m1_CanonicalProofOptions = O.from_str(
    [[_:c14n0 <http://purl.org/dc/terms/created> "2023-02-24T23:36:38Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#DataIntegrityProof> .
_:c14n0 <https://w3id.org/security#cryptosuite> "ecdsa-rdfc-2019"^^<https://w3id.org/security#cryptosuiteString> .
_:c14n0 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> .
_:c14n0 <https://w3id.org/security#verificationMethod> <did:key:zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP#zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP> .
]])
vector_h2 = '03f59e5b04ab575b1172cb684f22eede72f0e9033e0b5c67d0e2506768d6ce11'
vector_h1 = '3a8a522f689025727fb9d1f0fa99a618da023e8494ac74f51015d009d35abc2e'
vector_multikey_pk = 'zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP'
vector_multikey_sk = 'z42twTcNeSYcnqg1FLuSFs2bsGH3ZqbRHFmvS9XMsYhjxvHN'
vector_sg = O.from_hex('c6798ff29f725dfd39aa4daf60fbb423cf9baf4e157f6b49f112c201015c6e730dc877154e65cf467f8ee2b61ec86d98ed78334b1cc9f3dba2e1745f37205e92')
vector_m= O.from_hex('3a8a522f689025727fb9d1f0fa99a618da023e8494ac74f51015d009d35abc2e03f59e5b04ab575b1172cb684f22eede72f0e9033e0b5c67d0e2506768d6ce11')

controls(vector_m1_CanonicalProofOptions, vector_m2_CanonicalCredential, vector_h1, vector_h2, vector_multikey_pk,
    vector_multikey_sk, vector_m, vector_sg)

-- vector: A.5 Representation: ecdsa-jcs-2019 with curve P-256
vector_m2_CanonicalCredential = O.from_str(
    [[{"@context":["https://www.w3.org/ns/credentials/v2","https://www.w3.org/ns/credentials/examples/v2"],"credentialSubject":{"alumniOf":"The School of Examples","id":"did:example:abcdefgh"},"description":"A minimum viable example of an Alumni Credential.","id":"urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33","issuer":"https://vc.example/issuers/5678","name":"Alumni Credential","type":["VerifiableCredential","AlumniCredential"],"validFrom":"2023-01-01T00:00:00Z"}]])
vector_m1_CanonicalProofOptions = O.from_str(
    [[{"@context":["https://www.w3.org/ns/credentials/v2","https://www.w3.org/ns/credentials/examples/v2"],"created":"2023-02-24T23:36:38Z","cryptosuite":"ecdsa-jcs-2019","proofPurpose":"assertionMethod","type":"DataIntegrityProof","verificationMethod":"did:key:zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP#zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP"}]])
vector_h2 = '59b7cb6251b8991add1ce0bc83107e3db9dbbab5bd2c28f687db1a03abc92f19'
vector_h1 = 'fe5799489119c7fe3c528715e72bd39d2ec6b4ab345978df32e9a9312648ec25'
vector_multikey_pk = 'zDnaepBuvsQ8cpsWrVKw8fbpGpvPeNSjVPTWoq6cRqaYzBKVP'
vector_multikey_sk = 'z42twTcNeSYcnqg1FLuSFs2bsGH3ZqbRHFmvS9XMsYhjxvHN'
vector_sg = O.from_hex('f15c3b599eb9b3cad05df9d8e8b39a70a86375833b53743c764ac0a88c4457d60707fd7d073e03d906130631d87803f80a9824dc9939632ba92d418181be9d16')
vector_m= O.from_hex('fe5799489119c7fe3c528715e72bd39d2ec6b4ab345978df32e9a9312648ec2559b7cb6251b8991add1ce0bc83107e3db9dbbab5bd2c28f687db1a03abc92f19')

controls(vector_m1_CanonicalProofOptions, vector_m2_CanonicalCredential, vector_h1, vector_h2, vector_multikey_pk,
    vector_multikey_sk, vector_m, vector_sg)
