Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new test vectors for w3c-vc-di-ecdsa #1022

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions test/vectors/check_w3c-vc-di-ecdsa.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
-- 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 compress_ecdsa_pk(pk)
local x, y= P256.pubxy(pk)
local pfx = fif( BIG.parity(BIG.new(y) ), OCTET.from_hex('03'), OCTET.from_hex('02') )
local c_pk = pfx .. x

return c_pk
end

function uncompress_public_key(compressed_pk)
local p = BIG.new(O.from_hex('ffffffff00000001000000000000000000000000ffffffffffffffffffffffff'))
local a = BIG.new(O.from_hex('ffffffff00000001000000000000000000000000fffffffffffffffffffffffc'))
local b = BIG.new(O.from_hex('5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'))
local e = BIG.shr(p + INT.new(1), 2) -- e = (p+1)/4

local parity = compressed_pk:sub(1,2)
assert(parity == '02' or parity == '03')
local x = BIG.new(O.from_hex(compressed_pk:sub(3, #compressed_pk)))
-- y*y = x*x*x+a*x+b
local rhs = BIG.mod(BIG.modmul(BIG.modmul(x,x,p),x,p)+BIG.modmul(a,x,p)+b,p)

-- starting from here there are errors. It is not correct. I have to find a may to sqrt(y*y) in P256
local sqrt_rhs = rhs:modpower(e, p)
assert(BIG.modmul(sqrt_rhs,sqrt_rhs, p) == rhs)
if sqrt_rhs:parity() ~= (parity == '03') then -- this is a xor
sqrt_rhs = sqrt_rhs:modneg(p)
end
return O.to_hex(x) .. O.to_hex(sqrt_rhs)
end

function controls(vector_m1 ,vector_m2, vector_h1, vector_h2, vector_multikey_pk, vector_multikey_sk, vector_sg)
print("Run test to verify signature and public key of w3c ecdsa-vc")
-- multibase and multikey vectors conversions
local vector_pk= 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))

-- [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)
local sg= P256.sign(vector_sk, m)
local uncompressed_vector_pk= O.from_hex(uncompress_public_key(vector_pk))
assert(P256.verify(uncompressed_vector_pk, 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, 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= 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
assert(uncompressed_vector_pk==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')

controls(vector_m1_CanonicalProofOptions ,vector_m2_CanonicalCredential,
vector_h1, vector_h2, vector_multikey_pk, vector_multikey_sk, 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')

controls(vector_m1_CanonicalProofOptions ,vector_m2_CanonicalCredential,
vector_h1, vector_h2, vector_multikey_pk, vector_multikey_sk, 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')

controls(vector_m1_CanonicalProofOptions ,vector_m2_CanonicalCredential,
vector_h1, vector_h2, vector_multikey_pk, vector_multikey_sk, vector_sg)
4 changes: 4 additions & 0 deletions test/vectors/ecdsa_p256.bats
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ load ../bats_setup
@test "NIST ECDSA SigGen" {
${ZENROOM_EXECUTABLE} -a $T/ecdsa_p256_SigGen.txt $T/check_ecdsa_p256_sign.lua
}

@test "W3C Data Integrity ECDSA" {
${ZENROOM_EXECUTABLE} $T/check_w3c-vc-di-ecdsa.lua
}
Loading