### 1 unstable release

0.1.0 | Jun 9, 2021 |
---|

#**38** in #privacy

**MIT**license

295KB

1K
SLoC

# HashWires π :: Range proofs for issued credentials

A Rust implementation of the range proof scheme described in HashWires: Hyperefficient Credential-Based Range Proofs, accepted in Privacy Enhancing Technologies (PETS) 2021 conference, by *Konstantinos Chalkias and Shir Cohen and Kevin Lewi and Fredric Moezinia and Yolan Romailler*. A more simplified demonstration of how HashWires work is available as a ZKProof blogpost.

HashWires is a hash-based range proof protocol that is applicable in settings for which there is a trusted third party (typically a credential issuer) that can generate commitments. We refer to these as "credential-based" range proofs (CBRPs). It improves upon hashchain solutions that are typically restricted to micro-payments for small interval ranges, achieving an exponential speedup in proof generation and verification time. In terms of proof size and computational cost, we show that HashWires compares favorably against Bulletproofs for both 32- and 64-bit numeric values.

Although CBRPs are inherently less flexible than general zero-knowledge range proofs, we provide a number of applications in which a credential issuer can leverage HashWires to provide range proofs for private values, without having to rely on heavyweight cryptographic tools and assumptions.

## Potential Applications:

- KYC range proofs (e.g., older/younger than age proofs)
- 2D/3D location range proofs (you can
- Proof of income (e.g., to landlords) without revealing the exact bank account balance or payslip salary
- Timestamp ranges (e.g, for digital certificates)
- Top % rankings (e.g., online contest ranking)
- % range for ingredients (e.g., in food and chemical products, showing compliance but without revealing the recipe)
- Micro payments (e.g., gradually redeemable cashier checks)
- Auction systems, where bidders want to hide their available funds (as this leaks information on how far they can go)

Note: The commitments used in HashWires are not homomorphic and thus they cannot be used for adding confidential amounts in blockchain applications.

## Documentation

Let's assume that Alice is a trusted issuer and Bob is requesting a HashWires commitment for his age (he is 43 years
old). Carol is a verifier, who should be convinced that Bob is older that 21 years. They all agree on a

which defines how long each hash-chain can be and `base : u32`

`max_number_bits``:` `usize`

which denotes the bits of the maximum number
supported in this use case.Given Bob's age

, Alice picks a `value : BigUint`

`seed``:` `[``u8``]`

and instantiates a `Secret`

for this commitment as
`let` secret `=` `Secret``::``<`Blake3`>``::`gen`(``&`seed`,` `&`value`)``;`

. The `secret`

can be instantiated with any hash function (in
this example we are using Blake3).Alice can now generate a commitment by

. Currently this crate
can only support a `let` commitment `=` secret`.``commit``(`base`,` max_number_bits`)``;`

in the set of {2, 4, 16, 256}. If required, a commitment can be serialized using
`base`

and it will be provided to Bob (in practice signed by Alice's key).`let` commitment_bytes `=` commitment`.``serialize``(``)``;`

Bob can now generate a range proof by

, where
`let` proof `=` secret`.``prove``(`base`,` max_number_bits`,` `&`threshold`)``;`

is the challenge (range value) Carol is requesting (thus, 21 in our example).`threshold : BigUint`

Given the HashWires

and `commitment`

, Carol can verify the range proof's statement by
`proof`

, which will return a `commitment .verify(&proof, &threshold);`

`HwError`

if it fails.A sample full cycle

test:`prove_and_verify`

`//` A full HashWires cycle with serialized outputs.
`fn` `prove_and_verify``(`
`base``:` `u32`,
`max_number_bits``:` `usize`,
`value``:` `&`BigUint,
`threshold``:` `&`BigUint,
`)`` ``->` `Result``<``(``)`, HwError`>` `{`
`//` Pick a random 32-byte seed.
`let` `mut` rng `=` OsRng`;`
`let` `mut` seed `=` `vec!``[``0``u8``;` `32``]``;`
rng`.``fill_bytes``(``&``mut` seed`)``;`
`//` Generate secret.
`let` secret `=` `Secret``::``<`Blake3`>``::`gen`(``&`seed`,` `&`value`)``;`
`//` Generate and serialize commitment.
`let` commitment `=` secret`.``commit``(`base`,` max_number_bits`)``?``;`
`let` commitment_bytes `=` commitment`.``serialize``(``)``;`
`//` Generate and serialize a HashWires proof.
`let` proof `=` secret`.``prove``(`base`,` max_number_bits`,` `&`threshold`)``?``;`
`let` proof_bytes `=` proof`.``serialize``(``)``;`
`//` Verify a range proof over a commitment.
commitment`.``verify``(``&`proof`,` `&`threshold`)``?``;`
`Commitment``::``<`Blake3`>``::`deserialize`(``&`commitment_bytes`,` base`)`
`.``verify``(``&``Proof``::`deserialize`(``&`proof_bytes`)``?``,` `&`threshold`)`
`}`

## HashWires structure sample

Fig.1 Full snapshot of a HashWires commitment structure for the number 312 in base-4. Note that malleability protection is work in progress.

## Performance

The HashWires performance depends on 3 parameters: the selected base, the maximum number supported and the underlying hash function.

The benchmarks were run on a MacBook Pro2.4 GHz 8-Core Intel Core i9 CPU with 32GB or RAM. As shown, Blake3 performs better than SHA2 in our selected Intel CPU, although itβs true that in AMD Ryzen architectures that support SHA extensions BLAKE3 is only slightly faster than hardware-accelerated SHA-256. Another interesting result is that because proof generation internally regenerates the commitment to compute the final tree-inclusion proofs, it is slightly more expensive than commitment creation.

Efficiency comparison (in microseconds) between Bulletproofs with and without AVX2 support, and HashWires for 64-bit integers, different bases and hash functions.

scheme | Commit gen. | Proof gen. | Proof verify |
---|---|---|---|

Bulletproofs | 71 | 12099 | 1555 |

Bulletproofs AVX2 | 36 | 6516 | 938 |

HashWires b16 SHA2-256 | 274 | 278 | 84 |

HashWires b256 SHA2-256 | 651 | 656 | 619 |

HashWires b16 Blake3 | 101 | 103 | 31 |

HashWires b256 Blake3 | 260 | 263 | 230 |

## Contributors

The original authors of this code are Konstantinos Chalkias (@kchalkias), Kevin Lewi (@kevinlewi) and Yolan Romailler (@AnomalRoil). To learn more about contributing to this project, see this document.

## Disclaimers

This software is still evolving and it has not been audited. Use at your own risk.

## License

This project is MIT licensed.

#### Dependencies

~6MB

~117K SLoC