mirror of
https://github.com/biscuit-auth/biscuit.git
synced 2024-10-06 02:27:33 +03:00
add gamma signatures
This commit is contained in:
parent
5f55b60a0e
commit
d2b18c900f
@ -175,6 +175,40 @@ It has som slight differences in behaviour with the other methods, though:
|
||||
- generating a verif token requires access to the token (ie no HttpOnly cookies)
|
||||
- once a challenge token is generated, it cannot be attenuated again (might be a good thing or bad thing depending on the context)
|
||||
|
||||
### Aggregated gamma signatures
|
||||
|
||||
implementation of the scheme from https://eprint.iacr.org/2018/414.pdf
|
||||
|
||||
|
||||
#### Performance
|
||||
|
||||
Performance is on par with the VRF solution (it can be further optimized):
|
||||
|
||||
```
|
||||
test bench::sign_first_block ... bench: 104,957 ns/iter (+/- 14,308)
|
||||
test bench::sign_second_block ... bench: 106,246 ns/iter (+/- 17,039)
|
||||
test bench::sign_third_block ... bench: 106,122 ns/iter (+/- 10,631)
|
||||
test bench::verify_one_block ... bench: 280,323 ns/iter (+/- 48,385)
|
||||
test bench::verify_two_blocks ... bench: 466,553 ns/iter (+/- 136,446)
|
||||
test bench::verify_three_blocks ... bench: 644,827 ns/iter (+/- 108,173)
|
||||
```
|
||||
|
||||
#### Signature overhead
|
||||
|
||||
a Ristretto point can be stored in 32 bytes, a Scalar can be stored in 32 bytes
|
||||
|
||||
we will store 2 points (public key and "A" parameter) per block,
|
||||
and one scalar in the signature
|
||||
|
||||
|
||||
So, for the first method:
|
||||
- 1 block: 1 * 64 + 32 = 96 bytes
|
||||
- 2 blocks: 2 * 64 + 32 = 160 bytes
|
||||
- 5 blocks: 5 * 64 + 32 = 352 bytes
|
||||
- 10 blocks: 10 * 64 + 32 = 672 bytes
|
||||
- 20 blocks: 20 * 64 + 32 = 1312 bytes
|
||||
|
||||
|
||||
## Benchmarks summary
|
||||
|
||||
### Signing
|
||||
@ -185,6 +219,7 @@ It has som slight differences in behaviour with the other methods, though:
|
||||
| VRF 1 | 254 μs | 690 μs | 844 μs |
|
||||
| VRF 2 | 325 μs | 678 μs | 866 μs |
|
||||
| challenge | 325 μs | 402 μs | 405 μs |
|
||||
| gamma | 104 μs | 106 μs | 106 μs |
|
||||
|
||||
### Verifying
|
||||
|
||||
@ -194,6 +229,7 @@ It has som slight differences in behaviour with the other methods, though:
|
||||
| VRF 1 | 322 μs | 548 μs | 748 μs |
|
||||
| VRF 2 | 264 μs | 322 μs | 418 μs |
|
||||
| challenge | 308 μs | 472 μs | 624 μs |
|
||||
| gamma | 280 μs | 466 μs | 644 μs |
|
||||
|
||||
### Size overhead
|
||||
|
||||
@ -205,4 +241,5 @@ It has som slight differences in behaviour with the other methods, though:
|
||||
| VRF 1 | 160 | 256 | 544 | 1024 | 1984 |
|
||||
| VRF 2 | 160 | 224 | 416 | 736 | 1376 |
|
||||
| challenge (base token) | 128 | 224 | 512 | 992 | 1952 |
|
||||
| challenge (challenge token) | 192 | 288 | 576 | 1056 | 2016 |
|
||||
| challenge (challenge token) | 192 | 288 | 576 | 1056 | 2016 |
|
||||
| gamma | 96 | 160 | 352 | 672 | 1312 |
|
||||
|
1
experimentations/gamma/biscuit-gamma/.gitignore
vendored
Normal file
1
experimentations/gamma/biscuit-gamma/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
target/
|
381
experimentations/gamma/biscuit-gamma/Cargo.lock
generated
Normal file
381
experimentations/gamma/biscuit-gamma/Cargo.lock
generated
Normal file
@ -0,0 +1,381 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "biscuit-gamma"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clear_on_drop"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"subtle 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
|
||||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
||||
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
|
||||
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
|
||||
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d"
|
||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
|
||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
|
||||
"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
|
||||
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
||||
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
"checksum subtle 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01f40907d9ffc762709e4ff3eb4a6f6b41b650375a3f09ac92b641942b7fb082"
|
||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
13
experimentations/gamma/biscuit-gamma/Cargo.toml
Normal file
13
experimentations/gamma/biscuit-gamma/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "biscuit-gamma"
|
||||
version = "0.1.0"
|
||||
authors = ["Geoffroy Couprie <geo.couprie@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
curve25519-dalek = { version = "^1.0", features = ["serde"] }
|
||||
rand = "^0.6"
|
||||
sha2 = "^0.8"
|
||||
hmac = "^0.7"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
165
experimentations/gamma/biscuit-gamma/benches/gamma.rs
Normal file
165
experimentations/gamma/biscuit-gamma/benches/gamma.rs
Normal file
@ -0,0 +1,165 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
extern crate biscuit_gamma;
|
||||
extern crate rand;
|
||||
|
||||
use rand::rngs::OsRng;
|
||||
use biscuit_gamma::{KeyPair, Token, TokenSignature};
|
||||
|
||||
mod bench {
|
||||
use super::*;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn sign_first_block(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
b.iter(||{
|
||||
Token::new(&mut rng, &keypair1, &message1[..])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn sign_second_block(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
assert!(token2.verify(), "cannot verify second token");
|
||||
|
||||
b.iter(||{
|
||||
token1.append(&mut rng, &keypair2, &message2[..])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn sign_third_block(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
assert!(token2.verify(), "cannot verify second token");
|
||||
|
||||
println!("will derive a third token");
|
||||
|
||||
let message3 = b"!!!";
|
||||
let keypair3 = KeyPair::new(&mut rng);
|
||||
|
||||
let token3 = token2.append(&mut rng, &keypair3, &message3[..]);
|
||||
|
||||
assert!(token3.verify(), "cannot verify third token");
|
||||
|
||||
b.iter(||{
|
||||
token2.append(&mut rng, &keypair3, &message3[..])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn verify_one_block(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
b.iter(||{
|
||||
token1.verify()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn verify_two_blocks(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
assert!(token2.verify(), "cannot verify second token");
|
||||
|
||||
b.iter(||{
|
||||
token2.verify()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn verify_three_blocks(b: &mut Bencher) {
|
||||
let mut rng: OsRng = OsRng::new().unwrap();
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
assert!(token2.verify(), "cannot verify second token");
|
||||
|
||||
println!("will derive a third token");
|
||||
|
||||
let message3 = b"!!!";
|
||||
let keypair3 = KeyPair::new(&mut rng);
|
||||
|
||||
let token3 = token2.append(&mut rng, &keypair3, &message3[..]);
|
||||
|
||||
assert!(token3.verify(), "cannot verify third token");
|
||||
|
||||
b.iter(||{
|
||||
token3.verify()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
307
experimentations/gamma/biscuit-gamma/src/lib.rs
Normal file
307
experimentations/gamma/biscuit-gamma/src/lib.rs
Normal file
@ -0,0 +1,307 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate curve25519_dalek;
|
||||
extern crate rand;
|
||||
extern crate sha2;
|
||||
extern crate hmac;
|
||||
extern crate serde;
|
||||
|
||||
use sha2::{Digest, Sha512};
|
||||
use hmac::{Hmac, Mac};
|
||||
use rand::prelude::*;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use curve25519_dalek::{
|
||||
constants::RISTRETTO_BASEPOINT_POINT,
|
||||
ristretto::{RistrettoPoint},
|
||||
scalar::Scalar,
|
||||
traits::Identity
|
||||
};
|
||||
use std::ops::{Deref, Neg};
|
||||
|
||||
type HmacSha512 = Hmac<Sha512>;
|
||||
|
||||
|
||||
pub struct KeyPair {
|
||||
private: Scalar,
|
||||
pub public: RistrettoPoint,
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
pub fn new<T: Rng + CryptoRng>(rng: &mut T) -> Self {
|
||||
let private = Scalar::random(rng);
|
||||
let public = private * RISTRETTO_BASEPOINT_POINT;
|
||||
|
||||
KeyPair { private, public }
|
||||
}
|
||||
|
||||
pub fn sign<T: Rng + CryptoRng>(&self, rng: &mut T, message: &[u8]) -> (Scalar, Scalar) {
|
||||
let r = Scalar::random(rng);
|
||||
let A = r * RISTRETTO_BASEPOINT_POINT;
|
||||
let d = ECVRF_hash_points(&[A]);
|
||||
// FIXME: maybe there's a simpler hashing process
|
||||
let e = ECVRF_hash_points(&[self.public, ECVRF_hash_to_curve(RISTRETTO_BASEPOINT_POINT, message)]);
|
||||
let z = r*d - e*self.private;
|
||||
(d, z)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify(public: &RistrettoPoint, message: &[u8], signature: &(Scalar, Scalar)) -> bool {
|
||||
let (d, z) = signature;
|
||||
let e = ECVRF_hash_points(&[*public, ECVRF_hash_to_curve(RISTRETTO_BASEPOINT_POINT, message)]);
|
||||
let d_inv = d.invert();
|
||||
let A = z * d_inv * RISTRETTO_BASEPOINT_POINT + e * d_inv * public;
|
||||
|
||||
ECVRF_hash_points(&[A]) == *d
|
||||
}
|
||||
|
||||
pub struct Token {
|
||||
pub messages: Vec<Vec<u8>>,
|
||||
pub keys: Vec<RistrettoPoint>,
|
||||
pub signature: TokenSignature,
|
||||
}
|
||||
|
||||
impl Token {
|
||||
pub fn new<T: Rng + CryptoRng>(rng: &mut T, keypair: &KeyPair, message: &[u8]) -> Self {
|
||||
let signature = TokenSignature::new(rng, keypair, message);
|
||||
|
||||
Token {
|
||||
messages: vec![message.to_owned()],
|
||||
keys: vec![keypair.public],
|
||||
signature
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append<T: Rng + CryptoRng>(&self, rng: &mut T, keypair: &KeyPair, message: &[u8]) -> Self {
|
||||
let signature = self.signature.sign(rng, &self.keys, &self.messages, keypair, message);
|
||||
|
||||
let mut t = Token {
|
||||
messages: self.messages.clone(),
|
||||
keys: self.keys.clone(),
|
||||
signature
|
||||
};
|
||||
|
||||
t.messages.push(message.to_owned());
|
||||
t.keys.push(keypair.public);
|
||||
|
||||
t
|
||||
}
|
||||
|
||||
pub fn verify(&self) -> bool {
|
||||
self.signature.verify(&self.keys, &self.messages)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,Debug,Serialize,Deserialize)]
|
||||
pub struct TokenSignature {
|
||||
parameters: Vec<RistrettoPoint>,
|
||||
z: Scalar
|
||||
}
|
||||
|
||||
impl TokenSignature {
|
||||
pub fn new<T: Rng + CryptoRng>(rng: &mut T, keypair: &KeyPair, message: &[u8]) -> Self {
|
||||
let r = Scalar::random(rng);
|
||||
let A = r * RISTRETTO_BASEPOINT_POINT;
|
||||
let d = ECVRF_hash_points(&[A]);
|
||||
// FIXME: maybe there's a simpler hashing process
|
||||
let e = ECVRF_hash_points(&[keypair.public, ECVRF_hash_to_curve(RISTRETTO_BASEPOINT_POINT, message)]);
|
||||
let z = r*d - e * keypair.private;
|
||||
|
||||
TokenSignature {
|
||||
parameters: vec![A],
|
||||
z: z,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign<M: Deref<Target=[u8]>, T: Rng + CryptoRng>(&self, rng: &mut T, public_keys: &[RistrettoPoint],
|
||||
messages: &[M], keypair: &KeyPair, message: &[u8]) -> Self {
|
||||
let r = Scalar::random(rng);
|
||||
let A = r * RISTRETTO_BASEPOINT_POINT;
|
||||
let d = ECVRF_hash_points(&[A]);
|
||||
// FIXME: maybe there's a simpler hashing process
|
||||
let e = ECVRF_hash_points(&[keypair.public, ECVRF_hash_to_curve(RISTRETTO_BASEPOINT_POINT, message)]);
|
||||
let z = r*d - e * keypair.private;
|
||||
|
||||
let mut t = TokenSignature {
|
||||
parameters: self.parameters.clone(),
|
||||
z: self.z + z,
|
||||
};
|
||||
|
||||
t.parameters.push(A);
|
||||
t
|
||||
}
|
||||
|
||||
pub fn verify<M: Deref<Target=[u8]>>(&self, public_keys: &[RistrettoPoint], messages: &[M]) -> bool {
|
||||
if !(public_keys.len() == messages.len()
|
||||
&& public_keys.len() == self.parameters.len()) {
|
||||
println!("invalid data");
|
||||
return false;
|
||||
}
|
||||
|
||||
let zP = self.z * RISTRETTO_BASEPOINT_POINT;
|
||||
let eiXi = public_keys.iter().zip(messages).map(|(pubkey, message)| {
|
||||
let e = ECVRF_hash_points(&[*pubkey, ECVRF_hash_to_curve(RISTRETTO_BASEPOINT_POINT, message)]);
|
||||
e * pubkey
|
||||
}).fold(RistrettoPoint::identity(), |acc, point| acc + point);
|
||||
|
||||
let diAi = self.parameters.iter().map(|A| {
|
||||
let d = ECVRF_hash_points(&[*A]);
|
||||
d * A
|
||||
}).fold(RistrettoPoint::identity(), |acc, point| acc + point);
|
||||
|
||||
let res = zP + eiXi - diAi;
|
||||
|
||||
println!("verify identity={:?}", RistrettoPoint::identity());
|
||||
println!("verify res={:?}", res);
|
||||
println!("verify identity={:?}", RistrettoPoint::identity().compress());
|
||||
println!("verify res={:?}", res.compress());
|
||||
println!("returning: {:?}", RistrettoPoint::identity() == res);
|
||||
|
||||
RistrettoPoint::identity() == res
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//FIXME: the ECVRF_hash_to_curve1 looks like a hash and pray, but since
|
||||
// curve25519-dalek already has a hash to curve function, we can reuse it instead?
|
||||
pub fn ECVRF_hash_to_curve(point: RistrettoPoint, data: &[u8]) -> RistrettoPoint {
|
||||
let h = Sha512::new()
|
||||
.chain(point.compress().as_bytes())
|
||||
.chain(data);
|
||||
|
||||
RistrettoPoint::from_hash(h)
|
||||
}
|
||||
|
||||
//FIXME: is the output value in the right set?
|
||||
pub fn ECVRF_hash_points(points: &[RistrettoPoint]) -> Scalar {
|
||||
let mut h = Sha512::new();
|
||||
for point in points.iter() {
|
||||
h.input(point.compress().as_bytes());
|
||||
}
|
||||
|
||||
Scalar::from_hash(h)
|
||||
}
|
||||
|
||||
pub fn add_points(points: &[RistrettoPoint]) -> RistrettoPoint {
|
||||
assert!(points.len() > 0);
|
||||
|
||||
if points.len() == 1 {
|
||||
points[0]
|
||||
} else {
|
||||
let mut it = points.iter();
|
||||
let first = it.next().unwrap();
|
||||
it.fold(*first, |acc, pk| acc + pk)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ECVRF_nonce(sk: Scalar, point: RistrettoPoint) -> Scalar {
|
||||
let k = [0u8; 64];
|
||||
let v = [1u8; 64];
|
||||
|
||||
let mut mac = HmacSha512::new_varkey(&k[..]).unwrap();
|
||||
mac.input(&v[..]);
|
||||
mac.input(&[0]);
|
||||
mac.input(&sk.as_bytes()[..]);
|
||||
mac.input(point.compress().as_bytes());
|
||||
|
||||
let k = mac.result().code();
|
||||
|
||||
let mut mac = HmacSha512::new_varkey(&k[..]).unwrap();
|
||||
mac.input(&v[..]);
|
||||
mac.input(&[1]);
|
||||
mac.input(&sk.as_bytes()[..]);
|
||||
mac.input(point.compress().as_bytes());
|
||||
|
||||
let k = mac.result().code();
|
||||
|
||||
// the process in RFC 6979 is a bit ore complex than that
|
||||
let mut h = Sha512::new();
|
||||
h.input(k);
|
||||
|
||||
Scalar::from_hash(h)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn basic_signature() {
|
||||
let mut rng: StdRng = SeedableRng::seed_from_u64(0);
|
||||
|
||||
let message = b"hello world";
|
||||
let keypair = KeyPair::new(&mut rng);
|
||||
|
||||
let signature = keypair.sign(&mut rng, message);
|
||||
|
||||
assert!(verify(&keypair.public, message, &signature));
|
||||
|
||||
assert!(!verify(&keypair.public, b"AAAA", &signature));
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn three_messages() {
|
||||
//let mut rng: OsRng = OsRng::new().unwrap();
|
||||
//keep the same values in tests
|
||||
let mut rng: StdRng = SeedableRng::seed_from_u64(0);
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
assert!(token2.verify(), "cannot verify second token");
|
||||
|
||||
println!("will derive a third token");
|
||||
|
||||
let message3 = b"!!!";
|
||||
let keypair3 = KeyPair::new(&mut rng);
|
||||
|
||||
let token3 = token2.append(&mut rng, &keypair3, &message3[..]);
|
||||
|
||||
assert!(token3.verify(), "cannot verify third token");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_message() {
|
||||
//let mut rng: OsRng = OsRng::new().unwrap();
|
||||
//keep the same values in tests
|
||||
let mut rng: StdRng = SeedableRng::seed_from_u64(0);
|
||||
|
||||
let message1 = b"hello";
|
||||
let keypair1 = KeyPair::new(&mut rng);
|
||||
|
||||
let token1 = Token::new(&mut rng, &keypair1, &message1[..]);
|
||||
|
||||
assert!(token1.verify(), "cannot verify first token");
|
||||
|
||||
println!("will derive a second token");
|
||||
|
||||
let message2 = b"world";
|
||||
let keypair2 = KeyPair::new(&mut rng);
|
||||
|
||||
let mut token2 = token1.append(&mut rng, &keypair2, &message2[..]);
|
||||
|
||||
token2.messages[1] = Vec::from(&b"you"[..]);
|
||||
|
||||
assert!(!token2.verify(), "second token should not be valid");
|
||||
|
||||
println!("will derive a third token");
|
||||
|
||||
let message3 = b"!!!";
|
||||
let keypair3 = KeyPair::new(&mut rng);
|
||||
|
||||
let token3 = token2.append(&mut rng, &keypair3, &message3[..]);
|
||||
|
||||
assert!(!token3.verify(), "cannot verify third token");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user