I'm new to the list, a layman in cryptography, but a competent programmer. Seeking your help for a practical algorithm that I can implement please.


Let a prover P hold an identity document D, e.g. a passport, that contains a date of birth field dob.

A verifier V wants to check that:

  1. that I hold the document
  2. that D.dob is >= <some date>

All without P exposing D or V trusting P.

thanks and regards d.

  • 1
    $\begingroup$ That's not possible without further assumptions. A practical and simple version would be to use the eID functions, which are used by some countries. This is basically just using a trusted third party (the card issuer), which performs the check. If you just consider a paper passport, this is pretty much impossible without revealing the ID, because there is nothing to check. $\endgroup$
    – tylo
    May 31, 2017 at 7:53
  • 2
    $\begingroup$ You could take look at the TR 03110 documents specified by the German BSI. One problem is that this is not that suitable as an introduction to cryptography (but neither is this subject, I suppose). I guess the term you are looking for is attribute-based pseudonymous authentication. Or terms really :P $\endgroup$
    – Maarten Bodewes
    May 31, 2017 at 8:27
  • $\begingroup$ Is V permitted to know enough information to forge a D with any particular age? (This would imply that V is not allowed to know P's actual date of birth, but is permitted to know how P would answer if P was any arbitrary age) $\endgroup$
    – Cort Ammon
    Jun 1, 2017 at 19:35
  • $\begingroup$ Re tylo's comment: I think the prover will need to be an identity authority and issuer of said identity document. $\endgroup$
    – dazraf
    Jun 2, 2017 at 20:32
  • $\begingroup$ I must say, I am very grateful for all your thoughtful answers. As a newcomer to the field, it's wonderful to receive such help. Thank you. $\endgroup$
    – dazraf
    Jun 2, 2017 at 20:39

4 Answers 4


Here's a solution using RSA as the primitive. It's a bit slow though since this is more or less an RSA time lock. Time complexity is linear in the value n so n must be relatively small. Expect a desktop machine to take around n milliseconds to perform the proof which is really not great. The bulletproofs based solution is constant time (~20ms on a fast machine) with very large range of n. The hash chain solution will have linear time complexity like this one, but a smaller constant factor.

The protocol

Grace the government worker gives the prover Paul an identity document. One of the document fields is an age threshold proof value. This is a standard RSA signature over some public fields of Bob's identity document (EG:name, picture etc.) that Paul would use to prove he is Paul.

Instead of using the standard RSA signature algorithm to generate the signature, Grace uses a multiple of the private exponent when doing the operation. This is equivalent to applying the private operation multiple times.

age_proof=sig^(d^age) mod N

Note:the public exponent should be 3. Choosing e=65537 will make performance much much worse.

To verify this signature we have to apply the public operation age times to get back the original signature value.

sig=age_proof^(e^age) mod N

Note that sig, e and N are known to the verifier, age and age_proof are not known.

Suppose Paul is 35. If Alice wants paul to prove he is at least 20 years old, Paul first performs 15 public RSA operations on his proof of age value. He passes this value to Alice who performs an additional 20 exponentiations and gets back the original signature.

This can be seen as a chain of signatures. Grace, by repeatedly applying the private operation to Bob's signature value creates a chain of signature values which can be traversed in the forwards direction to get to the signature value.

What the system provides

Paul has an integer x Grace provides him with a proof value Px

Alice asks Paul to prove that x is larger than a bound y

  • Alice gives Paul y
  • Paul applies x-y public operations to degrade Px into a proof for Py
  • Paul gives Py to Alice
  • Alice applies y public operations to degrade Py into P0 which is a signature of some data about the thing that was signed (EG: Who owns the proof.)

Proof of age range

A more practical proof of age system would use two numbers. The numbers would be measured in days or hours and be the difference between the owner's data of birth and a date far in the past (say 1900AD) and a date far in the future (2200AD)

The first number, referenced to a date in the past proves youngness. The larger this number the more recent the date of birth.

The second number, referenced to a date in the future proves oldness. The larger this number the farther in the past the date of birth is and the older someone is.

This avoids the need to reissue or update cards as the card holder ages. The proof of youngness can be useful for businesses that want to implement youth discounts.

  • $\begingroup$ Thank you for an elegant algorithm and description. Very much appreciated. $\endgroup$
    – dazraf
    Jun 2, 2017 at 20:29

I recently found another solution, similar to @richard-thiessen, above, using hash chains. The basic idea comes from a paper by angel and walfish.

The prover would ask a trusted 3rd party to sign a document containing a) some necessary metadata that the verifier would want to see (maybe the name and the date the document was created) b) C = Hash^age(S)

The third party would then send this document to the prover, along with S

S is some random integer, and C is the end of the hash chain. If the prover is 60 years old (according to the document), 60 hashes must be calculated. b) his age in years, along with a timestamp for when the document was produced

When the verifier wants to challenge the prover's age, the verifier sends an integer q to the prover.

The prover then sends 2 hash chains to the verifier a) C (along with the metadata from the bank, signed by the bank) b) C' = Hash^(age-q)(S)

Similarly to the RSA solution above, the verifier then "finishes" the hash chain by performing q more hashes. Since finding the right pre-image of a hash is "hard", we know the prover couldn't guess C'. And since the verifier trusts the trusted source and verifies its signature, we know C is also correct.

This is simplified from the paper, but just a little bit.

  • $\begingroup$ Thank you ads for a practical solution and the very useful reference. I'm reading the paper. $\endgroup$
    – dazraf
    Jun 2, 2017 at 21:04

One would prove "more or equal" statement about integers with a proof of knowledge protocol of a non-negative witness. This could be done with (1) Lagrange theorem stating existence of representation as a sum of four squares, and (2) protocols for integers (basically, committing with a group of a hidden order).

Solution based on Lagrange theorem was introduced by Helger Lipmaa, "On Diophantine Complexity and Statistical Zero-Knowledge Arguments". Proofs with integers were introduced by Camenisch and Stadler.

For implementation, take a look at Idemix design tech report.

  • $\begingroup$ Thank you Vadym for very useful references. I'm reading them now :-) $\endgroup$
    – dazraf
    Jun 2, 2017 at 21:01

One attractive solution is to use a bulletproofs range proof.

Note:All the math in this answer assumes

  • prime order finite field with generator G (EG:ed25519)
  • Capital letters are group elements (EG: P,Q)
  • lowercase letters are scalars. (EG: s,t)
  • Additive notation.

The date of birth is represented as a Unix timestamp x or similar. Negative numbers are fine, all arithmetic will be done modulo the field order and so negative integers wrap around past zero to become large positive integers. Given a required age a (integer seconds) and a current date today (Unix timestamp) to prove a person is at least that old, just prove their birthday x is less than or equal to the Unix timestamp today-a.

This integer x is hidden using a Pedersen commitment. A commitment C for an integer x is a group element of a prime order group (usually an elliptic curve) in which discrete log is hard. It uses two publicly known generators H and G of a prime order group and a secret blinding integer r.

C = x*G+r*H

The identity document D would contain such a commitment rather than a numeric age.

Using homomorphism to transform inequalities

Pedersen commitments are homomorphic and can be added together with other commitments or with non-hidden values of the form V=v*G. Multiples of G can be added or subtracted from the commitment as shown below.

C = C + V = (xG+rH) + v*G = (x+v)G+rH`

The range proof allows proving that the value inside a commitment x is in the range 0x<2^n. Typically n is 64 although scaling to 128 bits has little additional cost.

We can transform statements of the form x≥a to (x-a)≥0 by adding a multiple of G to the commitment using the additive homomorphism of the commitment. Assuming (x-a)<2^64 for the largest possible x, this can be proven using a 64 bit range proof. For x<a we do (x+2^n-a)<2^n using the upper bound of the range proof.

Privacy concerns and after-the-fact deniability

All solutions proposed so far (including this one) leave permanent proofs that the number meets some bound. Peggy might not want a such a proof to be floating around forever.

It's possible to make an existing public coin zero knowledge proof like a bulletproof deniable in a number of ways, that all do roughly the same thing. The challenges in a public coin proof need to be unpredictable to the prover. So make them malleable in some way. Either have Victor choose and commit to them before the protocol starts so he and Peggy can collude to forge a proof making transcripts worthless or add a trapdoor to the Fiat-Shamir transform to allow roughly the same thing for non-interactive proofs (Sigma OR designated verifier proofs, Short lived proofs).

All of these are practically challenging since you’d need to modify the bulletproofs library. Not fun.

Fortunately there’s a more modular option that doesn’t require messing with the bulletproofs directly. We add a point P=r*H, representing a Pedersen commitment to 0 to the existing commitment C to obtain C'=C+P, then prove knowledge of r to Victor using some deniable proof. We can then use the commitment C' in a non-deniable proof as described earlier. This proof is worthless without knowing the commitment P opens to zero though.

To prove knowledge of r in an online protocol, just do a Diffie-Hellman key agreement with Victor, using H as the generator with victor choosing some multiple of H as an ephemeral key. Otherwise, given Victor’s public key Y, a solution to the following system of equations is persuasive:

R1=Hash(P|R2)*P+s1*H R2=Hash(Y|R1)*Y+s2*G

Peggy does:

  • R1=H*k for a random k
  • R2=Hash(Y|R1)*Y+s2*G for a random s2
  • s1=k - r*Hash(P|R2)
  • sends (P,R1,R2,s1,s2) to Victor

The equations can use entirely different groups. Victor could have a P-256 public key and the commitment could be in the ed25519 curve field as an example.

Knowing the discrete log of P or Y in the relevant base H or G allows that equation to be solved for a chosen R1 or R2. The two equations are cross coupled so a solution to the system can be found by knowing either of the relevant discrete logs.

Peggy can, optionally, use s2 as a private Diffie-Hellman key and send Victor the resulting shared secret s2*Y or some bits of its hash. Victor’s private key is then needed to verify the proof by computing the expected value making it unverifiable by third parties and trivial to forge with victor's key.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.