Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
irmago
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
IRMA
Github mirrors
irmago
Commits
6af7c6ab
Commit
6af7c6ab
authored
Jan 10, 2020
by
Sietse Ringers
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: client reuses revocation updates for all its credential instances of the same type and key
parent
bbc1c562
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
176 additions
and
155 deletions
+176
-155
irmaclient/client.go
irmaclient/client.go
+11
-6
irmaclient/credential.go
irmaclient/credential.go
+2
-8
irmaclient/irmaclient_test.go
irmaclient/irmaclient_test.go
+1
-1
irmaclient/revocation.go
irmaclient/revocation.go
+161
-139
irmaclient/session.go
irmaclient/session.go
+1
-1
No files found.
irmaclient/client.go
View file @
6af7c6ab
...
...
@@ -10,6 +10,7 @@ import (
"github.com/go-errors/errors"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
"github.com/privacybydesign/gabi/revocation"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/keyproof/common"
...
...
@@ -192,7 +193,7 @@ func New(
}
client
.
jobs
=
make
(
chan
func
(),
100
)
client
.
star
tRevocation
()
client
.
ini
tRevocation
()
client
.
StartJobs
()
return
client
,
schemeMgrErr
...
...
@@ -283,7 +284,7 @@ func (client *Client) addCredential(cred *credential) (err error) {
index
:=
-
1
for
_
,
attrlistlist
:=
range
client
.
attributes
{
for
i
,
attrs
:=
range
attrlistlist
{
if
attrs
.
Hash
()
==
cred
.
AttributeList
()
.
Hash
()
{
if
attrs
.
Hash
()
==
cred
.
attrs
.
Hash
()
{
index
=
i
break
}
...
...
@@ -307,7 +308,7 @@ func (client *Client) addCredential(cred *credential) (err error) {
}
for
i
:=
len
(
client
.
attrs
(
id
))
-
1
;
i
>=
0
;
i
--
{
// Go backwards through array because remove manipulates it
if
client
.
attrs
(
id
)[
i
]
.
EqualsExceptMetadata
(
cred
.
AttributeList
()
)
{
if
client
.
attrs
(
id
)[
i
]
.
EqualsExceptMetadata
(
cred
.
attrs
)
{
if
err
=
client
.
remove
(
id
,
i
,
false
);
err
!=
nil
{
return
}
...
...
@@ -316,7 +317,7 @@ func (client *Client) addCredential(cred *credential) (err error) {
}
// Append the new cred to our attributes and credentials
client
.
attributes
[
id
]
=
append
(
client
.
attrs
(
id
),
cred
.
AttributeList
()
)
client
.
attributes
[
id
]
=
append
(
client
.
attrs
(
id
),
cred
.
attrs
)
if
!
id
.
Empty
()
{
if
_
,
exists
:=
client
.
credentialsCache
[
id
];
!
exists
{
client
.
credentialsCache
[
id
]
=
make
(
map
[
int
]
*
credential
)
...
...
@@ -523,7 +524,7 @@ func (client *Client) credential(id irma.CredentialTypeIdentifier, counter int)
Signature
:
sig
,
NonRevocationWitness
:
witness
,
Pk
:
pk
,
},
client
.
Configuration
)
},
attrs
,
client
.
Configuration
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -772,6 +773,9 @@ func (client *Client) ProofBuilders(choice *irma.DisclosureChoice, request irma.
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
if
cred
.
attrs
.
Revoked
{
return
nil
,
nil
,
nil
,
revocation
.
ErrorRevoked
}
nonrev
:=
request
.
Base
()
.
RequestsRevocation
(
cred
.
CredentialType
()
.
Identifier
())
builder
,
err
=
cred
.
CreateDisclosureProofBuilder
(
grp
.
attrs
,
nonrev
)
if
err
!=
nil
{
...
...
@@ -895,7 +899,8 @@ func (client *Client) ConstructCredentials(msg []*gabi.IssueSignatureMessage, re
}
for
_
,
gabicred
:=
range
gabicreds
{
newcred
,
err
:=
newCredential
(
gabicred
,
client
.
Configuration
)
attrs
:=
irma
.
NewAttributeListFromInts
(
gabicred
.
Attributes
[
1
:
],
client
.
Configuration
)
newcred
,
err
:=
newCredential
(
gabicred
,
attrs
,
client
.
Configuration
)
if
err
!=
nil
{
return
err
}
...
...
irmaclient/credential.go
View file @
6af7c6ab
...
...
@@ -13,7 +13,7 @@ type credential struct {
attrs
*
irma
.
AttributeList
}
func
newCredential
(
gabicred
*
gabi
.
Credential
,
conf
*
irma
.
Configuration
)
(
*
credential
,
error
)
{
func
newCredential
(
gabicred
*
gabi
.
Credential
,
attrs
*
irma
.
AttributeList
,
conf
*
irma
.
Configuration
)
(
*
credential
,
error
)
{
meta
:=
irma
.
MetadataFromInt
(
gabicred
.
Attributes
[
1
],
conf
)
cred
:=
&
credential
{
Credential
:
gabicred
,
...
...
@@ -30,12 +30,6 @@ func newCredential(gabicred *gabi.Credential, conf *irma.Configuration) (*creden
if
err
!=
nil
{
return
nil
,
err
}
cred
.
attrs
=
attrs
return
cred
,
nil
}
func
(
cred
*
credential
)
AttributeList
()
*
irma
.
AttributeList
{
if
cred
.
attrs
==
nil
{
cred
.
attrs
=
irma
.
NewAttributeListFromInts
(
cred
.
Credential
.
Attributes
[
1
:
],
cred
.
MetadataAttribute
.
Conf
)
}
return
cred
.
attrs
}
irmaclient/irmaclient_test.go
View file @
6af7c6ab
...
...
@@ -243,7 +243,7 @@ func TestCredentialRemoval(t *testing.T) {
cred
,
err
:=
client
.
credential
(
id
,
0
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
cred
)
err
=
client
.
RemoveCredentialByHash
(
cred
.
AttributeList
()
.
Hash
())
err
=
client
.
RemoveCredentialByHash
(
cred
.
attrs
.
Hash
())
require
.
NoError
(
t
,
err
)
cred
,
err
=
client
.
credential
(
id
,
0
)
require
.
NoError
(
t
,
err
)
...
...
irmaclient/revocation.go
View file @
6af7c6ab
...
...
@@ -7,7 +7,6 @@ import (
"math"
"time"
"github.com/go-errors/errors"
"github.com/privacybydesign/gabi/revocation"
irma
"github.com/privacybydesign/irmago"
"github.com/sirupsen/logrus"
...
...
@@ -15,17 +14,17 @@ import (
const
nonrevUpdateInterval
=
10
// Once every 10 seconds
func
(
client
*
Client
)
star
tRevocation
()
{
func
(
client
*
Client
)
ini
tRevocation
()
{
// For every credential supporting revocation, compute nonrevocation caches in async jobs
for
credid
,
attrsets
:=
range
client
.
attributes
{
for
typ
,
attrsets
:=
range
client
.
attributes
{
for
i
,
attrs
:=
range
attrsets
{
if
attrs
.
CredentialType
()
==
nil
||
!
attrs
.
CredentialType
()
.
SupportsRevocation
()
{
continue
}
credid
:=
credid
// make copy of same name to capture the value for closure below
i
:=
i
// see https://golang.org/doc/faq#closures_and_goroutines
typ
:=
typ
// make copy of same name to capture the value for closure below
i
:=
i
// see https://golang.org/doc/faq#closures_and_goroutines
client
.
jobs
<-
func
()
{
if
err
:=
client
.
nonrev
CredPrepareCache
(
credid
,
i
);
err
!=
nil
{
if
err
:=
client
.
nonrev
PrepareCache
(
typ
,
i
);
err
!=
nil
{
client
.
reportError
(
err
)
}
}
...
...
@@ -40,12 +39,12 @@ func (client *Client) startRevocation() {
// We do this by every 10 seconds updating the credential with a low probability, which
// increases over time since the last update.
client
.
Configuration
.
Scheduler
.
Every
(
nonrevUpdateInterval
)
.
Seconds
()
.
Do
(
func
()
{
for
credid
,
attrsets
:=
range
client
.
attributes
{
for
typ
,
attrsets
:=
range
client
.
attributes
{
for
i
,
attrs
:=
range
attrsets
{
if
!
attrs
.
CredentialType
()
.
SupportsRevocation
()
{
if
attrs
.
CredentialType
()
==
nil
||
!
attrs
.
CredentialType
()
.
SupportsRevocation
()
{
continue
}
cred
,
err
:=
client
.
credential
(
credid
,
i
)
cred
,
err
:=
client
.
credential
(
typ
,
i
)
if
err
!=
nil
{
client
.
reportError
(
err
)
continue
...
...
@@ -59,19 +58,12 @@ func (client *Client) startRevocation() {
break
}
if
r
<
probability
(
cred
.
NonRevocationWitness
.
Updated
)
{
irma
.
Logger
.
Debugf
(
"scheduling nonrevocation witness remote update for %s-%d"
,
credid
,
i
)
irma
.
Logger
.
Debugf
(
"scheduling nonrevocation witness remote update for %s-%d"
,
typ
,
i
)
client
.
jobs
<-
func
()
{
updated
,
err
:=
cred
.
NonrevUpdateFromServer
(
client
.
Configuration
)
if
err
!=
nil
{
if
err
=
client
.
nonrevUpdateFromServer
(
typ
);
err
!=
nil
{
client
.
reportError
(
err
)
return
}
if
updated
{
if
err
=
client
.
nonrevCredPrepareCache
(
credid
,
i
);
err
!=
nil
{
client
.
reportError
(
err
)
return
}
}
}
}
}
...
...
@@ -79,157 +71,161 @@ func (client *Client) startRevocation() {
})
}
// probability returns a float between 0 and asymptote, representing a probability
// that asymptotically increases to the asymptote, reaching
// a reference probability at a reference index.
func
probability
(
lastUpdate
time
.
Time
)
float64
{
const
(
asymptote
=
1.0
/
3
// max probability
refindex
=
7
*
60
*
60
*
24
// Week
refprobability
=
0.75
*
asymptote
// probability after one week
)
f
:=
math
.
Tan
(
math
.
Pi
*
refprobability
/
(
2
*
asymptote
))
i
:=
time
.
Now
()
.
Sub
(
lastUpdate
)
.
Seconds
()
return
2
*
asymptote
/
math
.
Pi
*
math
.
Atan
(
i
/
refindex
*
f
)
}
// randomfloat between 0 and 1
func
randomfloat
()
(
float64
,
error
)
{
b
:=
make
([]
byte
,
4
)
_
,
err
:=
rand
.
Read
(
b
)
if
err
!=
nil
{
fmt
.
Println
(
"error:"
,
err
)
return
0
,
err
// nonrevPrepare updates the revocation state for each credential in the request
// requiring a nonrevocation proof, using the updates included in the request, or the remote
// revocation server if those do not suffice.
func
(
client
*
Client
)
nonrevPrepare
(
request
irma
.
SessionRequest
)
error
{
base
:=
request
.
Base
()
if
err
:=
base
.
RevocationConsistent
();
err
!=
nil
{
return
err
}
c
:=
float64
(
binary
.
BigEndian
.
Uint32
(
b
))
/
float64
(
^
uint32
(
0
))
// random int / max int
return
c
,
nil
}
func
(
client
*
Client
)
nonrevCredPrepareCache
(
credid
irma
.
CredentialTypeIdentifier
,
index
int
)
error
{
irma
.
Logger
.
WithFields
(
logrus
.
Fields
{
"credid"
:
credid
,
"index"
:
index
})
.
Debug
(
"Preparing cache"
)
cred
,
err
:=
client
.
credential
(
credid
,
index
)
if
err
!=
nil
{
return
err
for
typ
:=
range
request
.
Disclosure
()
.
Identifiers
()
.
CredentialTypes
{
credtype
:=
client
.
Configuration
.
CredentialTypes
[
typ
]
if
!
credtype
.
SupportsRevocation
()
{
continue
}
if
!
base
.
RequestsRevocation
(
typ
)
{
continue
}
if
err
:=
client
.
nonrevUpdate
(
typ
,
base
.
RevocationUpdates
[
typ
]);
err
!=
nil
{
return
err
}
}
return
cred
.
NonrevPrepareCache
()
return
nil
}
// NonrevPrepare updates the revocation state for each credential in the request
// requiring a nonrevocation proof, using the updates included in the request, or the remote
// revocation server if those do not suffice.
func
(
client
*
Client
)
NonrevPreprare
(
request
irma
.
SessionRequest
)
error
{
var
err
error
var
cred
*
credential
var
updated
bool
for
id
:=
range
request
.
Disclosure
()
.
Identifiers
()
.
CredentialTypes
{
typ
:=
client
.
Configuration
.
CredentialTypes
[
id
]
if
!
typ
.
SupportsRevocation
()
{
// nonrevUpdate updates all contained instances of the specified type, using the specified
// updates if present and if they suffice, and contacting the issuer's server to download updates
// otherwise.
func
(
client
*
Client
)
nonrevUpdate
(
typ
irma
.
CredentialTypeIdentifier
,
updates
map
[
uint
]
*
revocation
.
Update
)
error
{
lowest
:=
map
[
uint
]
uint64
{}
attrs
:=
client
.
attrs
(
typ
)
// Per credential and issuer key counter we may posess multiple credential instances.
// Of the nonrevocation witnesses of these, take the lowest index.
for
i
:=
0
;
i
<
len
(
attrs
);
i
++
{
cred
,
err
:=
client
.
credential
(
typ
,
i
)
if
err
!=
nil
{
return
err
}
if
cred
.
NonRevocationWitness
==
nil
{
continue
}
attrs
:=
client
.
attrs
(
id
)
for
i
:=
0
;
i
<
len
(
attrs
);
i
++
{
if
cred
,
err
=
client
.
credential
(
id
,
i
);
err
!=
nil
{
return
err
}
if
updated
,
err
=
cred
.
NonrevPrepare
(
client
.
Configuration
,
request
);
err
!=
nil
{
if
err
==
revocation
.
ErrorRevoked
{
attrs
[
i
]
.
Revoked
=
true
cred
.
AttributeList
()
.
Revoked
=
true
if
serr
:=
client
.
storage
.
StoreAttributes
(
client
.
attributes
);
serr
!=
nil
{
client
.
reportError
(
serr
)
return
err
}
client
.
handler
.
Revoked
(
&
irma
.
CredentialIdentifier
{
Type
:
cred
.
CredentialType
()
.
Identifier
(),
Hash
:
cred
.
AttributeList
()
.
Hash
(),
})
}
pkid
:=
cred
.
Pk
.
Counter
_
,
present
:=
lowest
[
pkid
]
if
!
present
||
cred
.
NonRevocationWitness
.
Accumulator
.
Index
<
lowest
[
pkid
]
{
lowest
[
pkid
]
=
cred
.
NonRevocationWitness
.
Accumulator
.
Index
}
}
// For each key counter, get an update message starting at the lowest index computed above,
// that can update all of our credential instance of the given type and key counter,
// using the specified update messags if they suffice, or the issuer's server otherwise.
u
:=
map
[
uint
]
*
revocation
.
Update
{}
for
counter
,
l
:=
range
lowest
{
update
:=
updates
[
counter
]
if
update
!=
nil
&&
len
(
update
.
Events
)
>
0
&&
update
.
Events
[
0
]
.
Index
<=
l
{
u
[
counter
]
=
update
}
else
{
var
err
error
u
[
counter
],
err
=
irma
.
RevocationClient
{
Conf
:
client
.
Configuration
}
.
FetchUpdateFrom
(
typ
,
counter
,
l
+
1
)
if
err
!=
nil
{
return
err
}
if
updated
{
if
err
=
client
.
storage
.
StoreSignature
(
cred
);
err
!=
nil
{
return
err
}
}
}
}
// Apply the update messages to all instances of the given type and key counter
for
counter
,
update
:=
range
u
{
if
err
:=
client
.
nonrevApplyUpdates
(
typ
,
counter
,
update
);
err
!=
nil
{
return
err
}
}
return
nil
}
// nonrevRepopulateCaches repopulates the consumed nonrevocation caches of the credentials involved
// in the request, in background jobs, after the request has finished.
func
(
client
*
Client
)
nonrevRepopulateCaches
(
request
irma
.
SessionRequest
)
{
for
id
:=
range
request
.
Disclosure
()
.
Identifiers
()
.
CredentialTypes
{
typ
:=
client
.
Configuration
.
CredentialTypes
[
id
]
if
!
typ
.
SupportsRevocation
()
{
func
(
client
*
Client
)
nonrevApplyUpdates
(
typ
irma
.
CredentialTypeIdentifier
,
counter
uint
,
update
*
revocation
.
Update
)
error
{
attrs
:=
client
.
attrs
(
typ
)
var
save
bool
for
i
:=
0
;
i
<
len
(
attrs
);
i
++
{
cred
,
err
:=
client
.
credential
(
typ
,
i
)
if
err
!=
nil
{
return
err
}
if
cred
.
NonRevocationWitness
==
nil
||
cred
.
Pk
.
Counter
!=
counter
{
continue
}
for
i
,
attrs
:=
range
client
.
attrs
(
id
)
{
if
attrs
.
CredentialType
()
==
nil
||
!
attrs
.
CredentialType
()
.
SupportsRevocation
()
{
continue
}
id
:=
id
i
:=
i
client
.
jobs
<-
func
()
{
if
err
:=
client
.
nonrevCredPrepareCache
(
id
,
i
);
err
!=
nil
{
client
.
reportError
(
err
)
}
}
updated
,
err
:=
cred
.
nonrevApplyUpdates
(
update
,
irma
.
RevocationKeys
{
Conf
:
client
.
Configuration
})
if
updated
{
save
=
true
}
if
err
==
revocation
.
ErrorRevoked
{
attrs
[
i
]
.
Revoked
=
true
cred
.
attrs
.
Revoked
=
true
save
=
true
client
.
handler
.
Revoked
(
&
irma
.
CredentialIdentifier
{
Type
:
cred
.
CredentialType
()
.
Identifier
(),
Hash
:
cred
.
attrs
.
Hash
(),
})
// Even if this credential is revoked during a session, we may have
// other instances that can satisfy the request. So don't return an
// error which would halt the session.
continue
}
if
err
!=
nil
{
return
err
}
}
}
// NonrevPrepare attempts to update the credential's nonrevocation witness from
// 1) the session request, and then 2) the revocation server if our witness is too far out of date.
// Returns whether or not the credential's nonrevocation state was updated. If so the caller should
// persist the updated credential to storage.
func
(
cred
*
credential
)
NonrevPrepare
(
conf
*
irma
.
Configuration
,
request
irma
.
SessionRequest
)
(
bool
,
error
)
{
credtype
:=
cred
.
CredentialType
()
.
Identifier
()
base
:=
request
.
Base
()
if
!
base
.
RequestsRevocation
(
credtype
)
{
return
false
,
nil
if
save
{
if
err
:=
client
.
storage
.
StoreAttributes
(
client
.
attributes
);
err
!=
nil
{
client
.
reportError
(
err
)
return
err
}
}
return
nil
}
if
err
:=
base
.
RevocationConsistent
();
err
!=
nil
{
return
false
,
err
func
(
client
*
Client
)
nonrevUpdateFromServer
(
typ
irma
.
CredentialTypeIdentifier
)
error
{
if
err
:=
client
.
nonrevUpdate
(
typ
,
map
[
uint
]
*
revocation
.
Update
{});
err
!=
nil
{
return
err
}
return
nil
}
// first try to update witness by applying the revocation update messages attached to the session request
var
(
revupdates
=
base
.
RevocationUpdates
[
credtype
][
cred
.
Pk
.
Counter
]
updated
bool
err
error
)
if
revupdates
==
nil
{
return
false
,
errors
.
Errorf
(
"revocation updates for key %d not found in session request"
,
cred
.
Pk
.
Counter
)
}
updated
,
err
=
cred
.
NonrevApplyUpdates
(
revupdates
,
irma
.
RevocationKeys
{
Conf
:
conf
})
func
(
client
*
Client
)
nonrevPrepareCache
(
typ
irma
.
CredentialTypeIdentifier
,
index
int
)
error
{
irma
.
Logger
.
WithFields
(
logrus
.
Fields
{
"credtype"
:
typ
,
"index"
:
index
})
.
Debug
(
"Preparing cache"
)
cred
,
err
:=
client
.
credential
(
typ
,
index
)
if
err
!=
nil
{
return
updated
,
err
}
count
:=
len
(
revupdates
.
Events
)
if
cred
.
NonRevocationWitness
.
Accumulator
.
Index
>=
revupdates
.
Events
[
count
-
1
]
.
Index
{
return
updated
,
nil
return
err
}
// nonrevocation witness is still out of date after applying the updates from the request:
// we were too far behind. Update from revocation server.
return
cred
.
NonrevUpdateFromServer
(
conf
)
return
cred
.
NonrevPrepareCache
()
}
func
(
cred
*
credential
)
NonrevUpdateFromServer
(
conf
*
irma
.
Configuration
)
(
bool
,
error
)
{
credtype
:=
cred
.
CredentialType
()
.
Identifier
()
revupdates
,
err
:=
irma
.
RevocationClient
{
Conf
:
conf
}
.
FetchUpdateFrom
(
credtype
,
cred
.
Pk
.
Counter
,
cred
.
NonRevocationWitness
.
Accumulator
.
Index
+
1
)
if
err
!=
nil
{
return
false
,
err
// nonrevRepopulateCaches repopulates the consumed nonrevocation caches of the credentials involved
// in the request, in background jobs, after the request has finished.
func
(
client
*
Client
)
nonrevRepopulateCaches
(
request
irma
.
SessionRequest
)
{
for
typ
:=
range
request
.
Disclosure
()
.
Identifiers
()
.
CredentialTypes
{
credtype
:=
client
.
Configuration
.
CredentialTypes
[
typ
]
if
!
credtype
.
SupportsRevocation
()
{
continue
}
for
i
:=
range
client
.
attrs
(
typ
)
{
typ
:=
typ
i
:=
i
client
.
jobs
<-
func
()
{
if
err
:=
client
.
nonrevPrepareCache
(
typ
,
i
);
err
!=
nil
{
client
.
reportError
(
err
)
}
}
}
}
return
cred
.
NonrevApplyUpdates
(
revupdates
,
irma
.
RevocationKeys
{
Conf
:
conf
})
}
//
N
onrevApplyUpdates updates the credential's nonrevocation witness using the specified messages,
//
n
onrevApplyUpdates updates the credential's nonrevocation witness using the specified messages,
// if they all verify and if their indices are ahead and adjacent to that of our witness.
func
(
cred
*
credential
)
N
onrevApplyUpdates
(
update
*
revocation
.
Update
,
keys
irma
.
RevocationKeys
)
(
bool
,
error
)
{
func
(
cred
*
credential
)
n
onrevApplyUpdates
(
update
*
revocation
.
Update
,
keys
irma
.
RevocationKeys
)
(
bool
,
error
)
{
oldindex
:=
cred
.
NonRevocationWitness
.
Accumulator
.
Index
pk
,
err
:=
keys
.
PublicKey
(
cred
.
CredentialType
()
.
IssuerIdentifier
(),
update
.
SignedAccumulator
.
PKCounter
)
...
...
@@ -242,3 +238,29 @@ func (cred *credential) NonrevApplyUpdates(update *revocation.Update, keys irma.
return
cred
.
NonRevocationWitness
.
Accumulator
.
Index
!=
oldindex
,
nil
}
// probability returns a float between 0 and asymptote, representing a probability
// that asymptotically increases to the asymptote, reaching
// a reference probability at a reference index.
func
probability
(
lastUpdate
time
.
Time
)
float64
{
const
(
asymptote
=
1.0
/
3
// max probability
refindex
=
7
*
60
*
60
*
24
// Week
refprobability
=
0.75
*
asymptote
// probability after one week
)
f
:=
math
.
Tan
(
math
.
Pi
*
refprobability
/
(
2
*
asymptote
))
i
:=
time
.
Now
()
.
Sub
(
lastUpdate
)
.
Seconds
()
return
2
*
asymptote
/
math
.
Pi
*
math
.
Atan
(
i
/
refindex
*
f
)
}
// randomfloat between 0 and 1
func
randomfloat
()
(
float64
,
error
)
{
b
:=
make
([]
byte
,
4
)
_
,
err
:=
rand
.
Read
(
b
)
if
err
!=
nil
{
fmt
.
Println
(
"error:"
,
err
)
return
0
,
err
}
c
:=
float64
(
binary
.
BigEndian
.
Uint32
(
b
))
/
float64
(
^
uint32
(
0
))
// random int / max int
return
c
,
nil
}
irmaclient/session.go
View file @
6af7c6ab
...
...
@@ -313,7 +313,7 @@ func (session *session) processSessionInfo() {
// Prepare and update all revocation state asynchroniously while the user makes her choices
go
func
()
{
session
.
prepRevocation
<-
session
.
client
.
NonrevPrepr
are
(
session
.
request
)
session
.
prepRevocation
<-
session
.
client
.
nonrevPrep
are
(
session
.
request
)
}()
// Ask for permission to execute the session
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment