2023-02-08 15:26:23 +00:00
{. used . }
import
2023-08-29 12:16:21 +00:00
std / [ os , json ] ,
chronos ,
2023-09-04 10:16:44 +00:00
testutils / unittests
2023-02-13 10:43:49 +00:00
import
2023-08-09 17:11:50 +00:00
.. / .. / waku / waku_keystore ,
2023-02-13 10:43:49 +00:00
. / testlib / common
2023-02-08 15:26:23 +00:00
2023-08-09 17:11:50 +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 "
defer : removeFile ( filepath )
let keystoreRes = createAppKeystore ( path = filepath ,
appInfo = testAppInfo )
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 "
defer : removeFile ( filepath )
# If no keystore exists at filepath, a new one is created for appInfo and empty credentials
let keystoreRes = loadAppKeystore ( path = filepath ,
appInfo = testAppInfo )
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 "
defer : removeFile ( filepath )
# 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 )
idNullifier = randomSeqByte ( rng [ ] , 32 )
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
var idCredential = IdentityCredential ( idTrapdoor : idTrapdoor , idNullifier : idNullifier , idSecretHash : idSecretHash , idCommitment : idCommitment )
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
2023-08-29 12:16:21 +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
2023-02-08 15:26:23 +00:00
let keystoreRes = addMembershipCredentials ( path = filepath ,
2023-08-29 12:16:21 +00:00
membership = membershipCredential ,
2023-02-08 15:26:23 +00:00
password = password ,
appInfo = testAppInfo )
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 "
defer : removeFile ( filepath )
# 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 )
idNullifier = randomSeqByte ( rng [ ] , 32 )
idSecretHash = randomSeqByte ( rng [ ] , 32 )
idCommitment = randomSeqByte ( rng [ ] , 32 )
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
2023-08-29 12:16:21 +00:00
var contract = MembershipContract ( chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 " )
var index = MembershipIndex ( 1 )
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
let keystoreRes = addMembershipCredentials ( path = filepath ,
2023-08-29 12:16:21 +00:00
membership = membershipCredential ,
2023-02-08 15:26:23 +00:00
password = password ,
appInfo = testAppInfo )
check :
keystoreRes . isOk ( )
# We test retrieval of credentials.
2023-08-29 12:16:21 +00:00
var expectedMembership = membershipCredential
let membershipQuery = KeystoreMembership ( membershipContract : contract ,
treeIndex : index )
2023-02-08 15:26:23 +00:00
var recoveredCredentialsRes = getMembershipCredentials ( path = filepath ,
password = password ,
2023-08-29 12:16:21 +00:00
query = membershipQuery ,
2023-02-08 15:26:23 +00:00
appInfo = testAppInfo )
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 "
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 )
let contract = MembershipContract ( chainId : " 5 " , address : " 0x0123456789012345678901234567890123456789 " )
let index = MembershipIndex ( 1 )
let 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 )
# We test retrieval of credentials.
let expectedMembership = membershipCredential
let membershipQuery = KeystoreMembership ( membershipContract : contract )
let recoveredCredentialsRes = getMembershipCredentials ( path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = testAppInfo )
assert ( recoveredCredentialsRes . isOk ( ) , $ recoveredCredentialsRes . error )
check : recoveredCredentialsRes . get ( ) = = expectedMembership
test " if the keystore contains multiple credentials, then error out if treeIndex has not been passed in " :
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 )
membershipCredential . treeIndex = MembershipIndex ( 2 )
let keystoreRes2 = addMembershipCredentials ( path = filepath ,
membership = membershipCredential ,
password = password ,
appInfo = testAppInfo )
assert ( keystoreRes2 . isOk ( ) , $ keystoreRes2 . error )
# We test retrieval of credentials.
let membershipQuery = KeystoreMembership ( membershipContract : contract )
let recoveredCredentialsRes = getMembershipCredentials ( path = filepath ,
password = password ,
query = membershipQuery ,
appInfo = testAppInfo )
check :
recoveredCredentialsRes . isErr ( )
recoveredCredentialsRes . error . kind = = KeystoreCredentialNotFoundError