2023-02-08 15:26:23 +00:00
{. used . }
2024-03-15 23:08:47 +00:00
import std / [ os , json ] , chronos , testutils / unittests
2024-07-05 22:03:38 +00:00
import waku / waku_keystore , . / testlib / common
2023-02-08 15:26:23 +00:00
2024-07-05 22:03:38 +00:00
from waku / waku_noise / noise_utils import randomSeqByte
2023-02-08 15:26:23 +00:00
procSuite " Credentials test suite " :
let testAppInfo = AppInfo ( application : " test " , appIdentifier : " 1234 " , version : " 0.1 " )
2023-02-13 10:43:49 +00:00
test " Create keystore " :
2023-02-08 15:26:23 +00:00
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-02-08 15:26:23 +00:00
2024-03-15 23:08:47 +00:00
let keystoreRes = createAppKeystore ( path = filepath , appInfo = testAppInfo )
2023-02-08 15:26:23 +00:00
check :
keystoreRes . isOk ( )
2023-02-13 10:43:49 +00:00
test " Load keystore " :
2023-02-08 15:26:23 +00:00
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-02-08 15:26:23 +00:00
# If no keystore exists at filepath, a new one is created for appInfo and empty credentials
2024-03-15 23:08:47 +00:00
let keystoreRes = loadAppKeystore ( path = filepath , appInfo = testAppInfo )
2023-02-08 15:26:23 +00:00
check :
keystoreRes . isOk ( )
let keystore = keystoreRes . get ( )
check :
keystore . hasKeys ( [ " application " , " appIdentifier " , " version " , " credentials " ] )
keystore [ " application " ] . getStr ( ) = = testAppInfo . application
keystore [ " appIdentifier " ] . getStr ( ) = = testAppInfo . appIdentifier
keystore [ " version " ] . getStr ( ) = = testAppInfo . version
# We assume the loaded keystore to not have credentials set (previous tests delete the keystore at filepath)
2023-08-29 12:16:21 +00:00
keystore [ " credentials " ] . len ( ) = = 0
2023-02-08 15:26:23 +00:00
2023-02-13 10:43:49 +00:00
test " Add credentials to keystore " :
2023-02-08 15:26:23 +00:00
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-02-08 15:26:23 +00:00
# We generate a random identity credential (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
var
idTrapdoor = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idNullifier = randomSeqByte ( rng [ ] , 32 )
2023-02-08 15:26:23 +00:00
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
var idCredential = IdentityCredential (
idTrapdoor : idTrapdoor ,
idNullifier : idNullifier ,
idSecretHash : idSecretHash ,
idCommitment : idCommitment ,
)
2023-02-08 15:26:23 +00:00
2024-03-15 23:08:47 +00:00
var contract = MembershipContract (
chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 "
)
2023-08-29 12:16:21 +00:00
var index = MembershipIndex ( 1 )
2023-02-08 15:26:23 +00:00
2024-03-15 23:08:47 +00:00
let membershipCredential = KeystoreMembership (
membershipContract : contract , treeIndex : index , identityCredential : idCredential
)
2023-02-08 15:26:23 +00:00
let password = " %m0um0ucoW% "
2023-02-13 10:43:49 +00:00
2024-03-15 23:08:47 +00:00
let keystoreRes = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
2023-02-08 15:26:23 +00:00
check :
keystoreRes . isOk ( )
2023-02-13 10:43:49 +00:00
test " Add/retrieve credentials in keystore " :
2023-02-08 15:26:23 +00:00
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-02-08 15:26:23 +00:00
# We generate two random identity credentials (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
var
2023-08-29 12:16:21 +00:00
idTrapdoor = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idNullifier = randomSeqByte ( rng [ ] , 32 )
2023-08-29 12:16:21 +00:00
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idCredential = IdentityCredential (
idTrapdoor : idTrapdoor ,
idNullifier : idNullifier ,
idSecretHash : idSecretHash ,
idCommitment : idCommitment ,
)
2023-02-13 10:43:49 +00:00
2023-02-08 15:26:23 +00:00
# We generate two distinct membership groups
2024-03-15 23:08:47 +00:00
var contract = MembershipContract (
chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 "
)
2023-08-29 12:16:21 +00:00
var index = MembershipIndex ( 1 )
2024-03-15 23:08:47 +00:00
var membershipCredential = KeystoreMembership (
membershipContract : contract , treeIndex : index , identityCredential : idCredential
)
2023-02-08 15:26:23 +00:00
let password = " %m0um0ucoW% "
2023-02-13 10:43:49 +00:00
2023-02-08 15:26:23 +00:00
# We add credentials to the keystore. Note that only 3 credentials should be effectively added, since rlnMembershipCredentials3 is equal to membershipCredentials2
2024-03-15 23:08:47 +00:00
let keystoreRes = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
2023-02-08 15:26:23 +00:00
check :
keystoreRes . isOk ( )
# We test retrieval of credentials.
2023-08-29 12:16:21 +00:00
var expectedMembership = membershipCredential
2024-03-15 23:08:47 +00:00
let membershipQuery =
KeystoreMembership ( membershipContract : contract , treeIndex : index )
2023-02-08 15:26:23 +00:00
2024-03-15 23:08:47 +00:00
var recoveredCredentialsRes = getMembershipCredentials (
path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = testAppInfo ,
)
2023-02-08 15:26:23 +00:00
check :
recoveredCredentialsRes . isOk ( )
2023-08-29 12:16:21 +00:00
recoveredCredentialsRes . get ( ) = = expectedMembership
2023-02-08 15:26:23 +00:00
2023-09-04 10:16:44 +00:00
test " if the keystore contains only one credential, fetch that irrespective of treeIndex " :
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-09-04 10:16:44 +00:00
# We generate random identity credentials (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
let
idTrapdoor = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idNullifier = randomSeqByte ( rng [ ] , 32 )
2023-09-04 10:16:44 +00:00
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idCredential = IdentityCredential (
idTrapdoor : idTrapdoor ,
idNullifier : idNullifier ,
idSecretHash : idSecretHash ,
idCommitment : idCommitment ,
)
let contract = MembershipContract (
chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 "
)
2023-09-04 10:16:44 +00:00
let index = MembershipIndex ( 1 )
2024-03-15 23:08:47 +00:00
let membershipCredential = KeystoreMembership (
membershipContract : contract , treeIndex : index , identityCredential : idCredential
)
2023-09-04 10:16:44 +00:00
let password = " %m0um0ucoW% "
2024-03-15 23:08:47 +00:00
let keystoreRes = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
2023-09-04 10:16:44 +00:00
assert ( keystoreRes . isOk ( ) , $ keystoreRes . error )
# We test retrieval of credentials.
let expectedMembership = membershipCredential
let membershipQuery = KeystoreMembership ( membershipContract : contract )
2024-03-15 23:08:47 +00:00
let recoveredCredentialsRes = getMembershipCredentials (
path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = testAppInfo ,
)
2023-09-04 10:16:44 +00:00
assert ( recoveredCredentialsRes . isOk ( ) , $ recoveredCredentialsRes . error )
2024-03-15 23:08:47 +00:00
check :
recoveredCredentialsRes . get ( ) = = expectedMembership
2023-09-04 10:16:44 +00:00
test " if the keystore contains multiple credentials, then error out if treeIndex has not been passed in " :
let filepath = " ./testAppKeystore.txt "
2024-03-15 23:08:47 +00:00
defer :
removeFile ( filepath )
2023-09-04 10:16:44 +00:00
# We generate random identity credentials (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
let
idTrapdoor = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idNullifier = randomSeqByte ( rng [ ] , 32 )
2023-09-04 10:16:44 +00:00
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
2024-03-15 23:08:47 +00:00
idCredential = IdentityCredential (
idTrapdoor : idTrapdoor ,
idNullifier : idNullifier ,
idSecretHash : idSecretHash ,
idCommitment : idCommitment ,
)
2023-09-04 10:16:44 +00:00
# We generate two distinct membership groups
2024-03-15 23:08:47 +00:00
let contract = MembershipContract (
chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 "
)
2023-09-04 10:16:44 +00:00
let index = MembershipIndex ( 1 )
2024-03-15 23:08:47 +00:00
var membershipCredential = KeystoreMembership (
membershipContract : contract , treeIndex : index , identityCredential : idCredential
)
2023-09-04 10:16:44 +00:00
let password = " %m0um0ucoW% "
2024-03-15 23:08:47 +00:00
let keystoreRes = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
2023-09-04 10:16:44 +00:00
assert ( keystoreRes . isOk ( ) , $ keystoreRes . error )
membershipCredential . treeIndex = MembershipIndex ( 2 )
2024-03-15 23:08:47 +00:00
let keystoreRes2 = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
2023-09-04 10:16:44 +00:00
assert ( keystoreRes2 . isOk ( ) , $ keystoreRes2 . error )
# We test retrieval of credentials.
let membershipQuery = KeystoreMembership ( membershipContract : contract )
2024-03-15 23:08:47 +00:00
let recoveredCredentialsRes = getMembershipCredentials (
path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = testAppInfo ,
)
2023-09-04 10:16:44 +00:00
check :
recoveredCredentialsRes . isErr ( )
recoveredCredentialsRes . error . kind = = KeystoreCredentialNotFoundError
2024-05-01 17:35:22 +00:00
test " if a keystore exists, but the keystoreQuery doesn ' t match it " :
let filepath = " ./testAppKeystore.txt "
defer :
removeFile ( filepath )
# We generate random identity credentials (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
let
idTrapdoor = randomSeqByte ( rng [ ] , 32 )
idNullifier = randomSeqByte ( rng [ ] , 32 )
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
idCredential = IdentityCredential (
idTrapdoor : idTrapdoor ,
idNullifier : idNullifier ,
idSecretHash : idSecretHash ,
idCommitment : idCommitment ,
)
# We generate two distinct membership groups
let contract = MembershipContract (
chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 "
)
let index = MembershipIndex ( 1 )
var membershipCredential = KeystoreMembership (
membershipContract : contract , treeIndex : index , identityCredential : idCredential
)
let password = " %m0um0ucoW% "
let keystoreRes = addMembershipCredentials (
path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo ,
)
assert ( keystoreRes . isOk ( ) , $ keystoreRes . error )
let badTestAppInfo =
AppInfo ( application : " _bad_test_ " , appIdentifier : " 1234 " , version : " 0.1 " )
# We test retrieval of credentials.
let membershipQuery = KeystoreMembership ( membershipContract : contract )
let recoveredCredentialsRes = getMembershipCredentials (
path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = badTestAppInfo ,
)
check :
recoveredCredentialsRes . isErr ( )
recoveredCredentialsRes . error . kind = = KeystoreJsonValueMismatchError
recoveredCredentialsRes . error . msg = =
" Application does not match. Expected ' _bad_test_ ' but got ' test ' "