зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1892204: Update libprio-rs dependency to 0.16 r=tcampbell,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D207843
This commit is contained in:
Родитель
68b0f2af19
Коммит
0b72f2ffda
|
@ -585,9 +585,9 @@ checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
|||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
|
@ -2196,9 +2196,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
|
||||
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
|
@ -4538,9 +4538,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
|||
|
||||
[[package]]
|
||||
name = "prio"
|
||||
version = "0.15.3"
|
||||
version = "0.16.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3163d19b7d8bc08c7ab6b74510f5e048c0937509d14c28b8919d2baf8cb9387"
|
||||
checksum = "5cec5eb0d28eee4ea74be34b28ed4c625e88c54ff83c21b412a5ea7cc48624ae"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"getrandom",
|
||||
|
|
|
@ -71,6 +71,13 @@ user-id = 189
|
|||
user-login = "BurntSushi"
|
||||
user-name = "Andrew Gallant"
|
||||
|
||||
[[publisher.byteorder]]
|
||||
version = "1.5.0"
|
||||
when = "2023-10-06"
|
||||
user-id = 189
|
||||
user-login = "BurntSushi"
|
||||
user-name = "Andrew Gallant"
|
||||
|
||||
[[publisher.bytes]]
|
||||
version = "1.4.0"
|
||||
when = "2023-01-31"
|
||||
|
@ -412,6 +419,12 @@ when = "2023-10-03"
|
|||
user-id = 213776
|
||||
user-login = "divviup-github-automation"
|
||||
|
||||
[[publisher.prio]]
|
||||
version = "0.16.2"
|
||||
when = "2024-03-19"
|
||||
user-id = 213776
|
||||
user-login = "divviup-github-automation"
|
||||
|
||||
[[publisher.proc-macro2]]
|
||||
version = "1.0.74"
|
||||
when = "2024-01-02"
|
||||
|
@ -1382,6 +1395,16 @@ criteria = "safe-to-deploy"
|
|||
delta = "0.2.9 -> 0.2.10"
|
||||
notes = "These changes include some new `unsafe` code for the `emscripten` and `psvita` targets, but all it does is call `libc::getentropy`."
|
||||
|
||||
[[audits.isrg.audits.getrandom]]
|
||||
who = "David Cook <dcook@divviup.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.2.11 -> 0.2.12"
|
||||
|
||||
[[audits.isrg.audits.getrandom]]
|
||||
who = "David Cook <dcook@divviup.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.2.12 -> 0.2.14"
|
||||
|
||||
[[audits.isrg.audits.keccak]]
|
||||
who = "David Cook <dcook@divviup.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"3a745d94ee9dce0d9dc638c02078cd5001d3d9d12d58b4f220c0101e32cfc16a","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"8585455e5a0e638cf5d489a21e286e93680f835cb8a13595918b5eb7c8c7f212","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"9d57556868344534de2489317e3c6bb611348ecd44438dcb982bd8d2a55a5a1b","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"a80bf3cd446c9b6c0cca3865c4de047bdf4644b74cdf696822f8ff87adfa1fca","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/io.rs":"9612530634d0e7ce9887a23836b58c0d972c1f45b05d9ada8355961567075627","src/lib.rs":"813ce6a8beafee3fd4e63325d783108aa02e8c57e412bc97580191d84082fbc9"},"package":"14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"}
|
||||
{"files":{"CHANGELOG.md":"c1cb69be6db5933c4bb4ebb6591e0fe3e7b97d491face3abcf947383c218bb31","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"94ba374cb26f3c68fb83da2e5e7dce85920fc4fb827620b06b39d71a9d0e1e18","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"2f2d64924c35b7203e3e3f3d136fcb714281762d145ca3513246da5547b1d014","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"8b114080042d3292ec8de425904e4114b7f532fe3add0d807521e6cc166a17ea","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/io.rs":"9612530634d0e7ce9887a23836b58c0d972c1f45b05d9ada8355961567075627","src/lib.rs":"ab3394c385b32457795931440cfb8dbca70ba5d9e1a428fcf651f7ccb2d6c34f"},"package":"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"}
|
|
@ -1,3 +1,7 @@
|
|||
**WARNING:** This CHANGELOG is no longer updated. The activity for this project
|
||||
is sparse enough that you should refer to the commit log instead.
|
||||
|
||||
|
||||
1.3.4
|
||||
=====
|
||||
This patch release squashes deprecation warnings for the `try!` macro, in
|
||||
|
|
|
@ -3,33 +3,44 @@
|
|||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
version = "1.5.0"
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
exclude = ["/ci/*"]
|
||||
description = "Library for reading/writing numbers in big-endian and little-endian."
|
||||
homepage = "https://github.com/BurntSushi/byteorder"
|
||||
documentation = "https://docs.rs/byteorder"
|
||||
readme = "README.md"
|
||||
keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
|
||||
categories = ["encoding", "parsing", "no-std"]
|
||||
keywords = [
|
||||
"byte",
|
||||
"endian",
|
||||
"big-endian",
|
||||
"little-endian",
|
||||
"binary",
|
||||
]
|
||||
categories = [
|
||||
"encoding",
|
||||
"parsing",
|
||||
"no-std",
|
||||
]
|
||||
license = "Unlicense OR MIT"
|
||||
repository = "https://github.com/BurntSushi/byteorder"
|
||||
|
||||
[profile.bench]
|
||||
opt-level = 3
|
||||
|
||||
[lib]
|
||||
name = "byteorder"
|
||||
bench = false
|
||||
|
||||
[dev-dependencies.quickcheck]
|
||||
version = "0.9.2"
|
||||
default-features = false
|
||||
|
|
|
@ -4,7 +4,7 @@ This crate provides convenience methods for encoding and decoding
|
|||
numbers in either big-endian or little-endian order.
|
||||
|
||||
[![Build status](https://github.com/BurntSushi/byteorder/workflows/ci/badge.svg)](https://github.com/BurntSushi/byteorder/actions)
|
||||
[![](https://meritbadge.herokuapp.com/byteorder)](https://crates.io/crates/byteorder)
|
||||
[![crates.io](https://img.shields.io/crates/v/byteorder.svg)](https://crates.io/crates/byteorder)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).
|
||||
|
||||
|
@ -56,6 +56,20 @@ byteorder = { version = "1", default-features = false }
|
|||
```
|
||||
|
||||
|
||||
### Minimum Rust version policy
|
||||
|
||||
This crate's minimum supported `rustc` version is `1.60.0`.
|
||||
|
||||
The current policy is that the minimum Rust version required to use this crate
|
||||
can be increased in minor version updates. For example, if `crate 1.0` requires
|
||||
Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust
|
||||
1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum
|
||||
version of Rust.
|
||||
|
||||
In general, this crate will be conservative with respect to the minimum
|
||||
supported version of Rust.
|
||||
|
||||
|
||||
### Alternatives
|
||||
|
||||
Note that as of Rust 1.32, the standard numeric types provide built-in methods
|
||||
|
|
|
@ -321,4 +321,6 @@ macro_rules! bench_slice {
|
|||
};
|
||||
}
|
||||
|
||||
bench_slice!(slice_u16, u16, read_u16_into, write_u16_into);
|
||||
bench_slice!(slice_u64, u64, read_u64_into, write_u64_into);
|
||||
bench_slice!(slice_i64, i64, read_i64_into, write_i64_into);
|
||||
|
|
|
@ -69,9 +69,13 @@ cases.
|
|||
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// When testing under miri, we disable tests that take too long. But this
|
||||
// provokes lots of dead code warnings. So we just squash them.
|
||||
#![cfg_attr(miri, allow(dead_code, unused_macros))]
|
||||
|
||||
use core::{
|
||||
convert::TryInto, fmt::Debug, hash::Hash, ptr::copy_nonoverlapping, slice,
|
||||
convert::TryInto, fmt::Debug, hash::Hash, mem::align_of,
|
||||
ptr::copy_nonoverlapping, slice,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
|
@ -1202,6 +1206,7 @@ pub trait ByteOrder:
|
|||
#[inline]
|
||||
fn read_f32_into(src: &[u8], dst: &mut [f32]) {
|
||||
let dst = unsafe {
|
||||
const _: () = assert!(align_of::<u32>() <= align_of::<f32>());
|
||||
slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
|
||||
};
|
||||
Self::read_u32_into(src, dst);
|
||||
|
@ -1263,6 +1268,7 @@ pub trait ByteOrder:
|
|||
#[inline]
|
||||
fn read_f64_into(src: &[u8], dst: &mut [f64]) {
|
||||
let dst = unsafe {
|
||||
const _: () = assert!(align_of::<u64>() <= align_of::<f64>());
|
||||
slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
|
||||
};
|
||||
Self::read_u64_into(src, dst);
|
||||
|
@ -1895,74 +1901,36 @@ pub type NativeEndian = LittleEndian;
|
|||
#[cfg(target_endian = "big")]
|
||||
pub type NativeEndian = BigEndian;
|
||||
|
||||
/// Copies $size bytes from a number $n to a &mut [u8] $dst. $ty represents the
|
||||
/// numeric type of $n and $which must be either to_be or to_le, depending on
|
||||
/// which endianness one wants to use when writing to $dst.
|
||||
/// Copies a &[u8] $src into a &mut [$ty] $dst for the endianness given by
|
||||
/// $from_bytes (must be either from_be_bytes or from_le_bytes).
|
||||
///
|
||||
/// This macro is only safe to call when $ty is a numeric type and $size ==
|
||||
/// size_of::<$ty>() and where $dst is a &mut [u8].
|
||||
macro_rules! unsafe_write_num_bytes {
|
||||
($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{
|
||||
assert!($size <= $dst.len());
|
||||
unsafe {
|
||||
// N.B. https://github.com/rust-lang/rust/issues/22776
|
||||
let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
|
||||
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
|
||||
/// Panics if $src.len() != $dst.len() * size_of::<$ty>().
|
||||
macro_rules! read_slice {
|
||||
($src:expr, $dst:expr, $ty:ty, $from_bytes:ident) => {{
|
||||
const SIZE: usize = core::mem::size_of::<$ty>();
|
||||
// Check types:
|
||||
let src: &[u8] = $src;
|
||||
let dst: &mut [$ty] = $dst;
|
||||
assert_eq!(src.len(), dst.len() * SIZE);
|
||||
for (src, dst) in src.chunks_exact(SIZE).zip(dst.iter_mut()) {
|
||||
*dst = <$ty>::$from_bytes(src.try_into().unwrap());
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Copies a &[u8] $src into a &mut [<numeric>] $dst for the endianness given
|
||||
/// by $which (must be either to_be or to_le).
|
||||
/// Copies a &[$ty] $src into a &mut [u8] $dst for the endianness given by
|
||||
/// $from_bytes (must be either from_be_bytes or from_le_bytes).
|
||||
///
|
||||
/// This macro is only safe to call when $src and $dst are &[u8] and &mut [u8],
|
||||
/// respectively. The macro will panic if $src.len() != $size * $dst.len(),
|
||||
/// where $size represents the size of the integers encoded in $src.
|
||||
macro_rules! unsafe_read_slice {
|
||||
($src:expr, $dst:expr, $size:expr, $which:ident) => {{
|
||||
assert_eq!($src.len(), $size * $dst.len());
|
||||
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
$src.as_ptr(),
|
||||
$dst.as_mut_ptr() as *mut u8,
|
||||
$src.len(),
|
||||
);
|
||||
}
|
||||
for v in $dst.iter_mut() {
|
||||
*v = v.$which();
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Copies a &[$ty] $src into a &mut [u8] $dst, where $ty must be a numeric
|
||||
/// type. This panics if size_of::<$ty>() * $src.len() != $dst.len().
|
||||
///
|
||||
/// This macro is only safe to call when $src is a slice of numeric types and
|
||||
/// $dst is a &mut [u8] and where $ty represents the type of the integers in
|
||||
/// $src.
|
||||
macro_rules! unsafe_write_slice_native {
|
||||
($src:expr, $dst:expr, $ty:ty) => {{
|
||||
let size = core::mem::size_of::<$ty>();
|
||||
assert_eq!(size * $src.len(), $dst.len());
|
||||
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
$src.as_ptr() as *const u8,
|
||||
$dst.as_mut_ptr(),
|
||||
$dst.len(),
|
||||
);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Panics if $src.len() * size_of::<$ty>() != $dst.len().
|
||||
macro_rules! write_slice {
|
||||
($src:expr, $dst:expr, $ty:ty, $size:expr, $write:expr) => {{
|
||||
assert!($size == ::core::mem::size_of::<$ty>());
|
||||
assert_eq!($size * $src.len(), $dst.len());
|
||||
|
||||
for (&n, chunk) in $src.iter().zip($dst.chunks_mut($size)) {
|
||||
$write(chunk, n);
|
||||
($src:expr, $dst:expr, $ty:ty, $to_bytes:ident) => {{
|
||||
const SIZE: usize = core::mem::size_of::<$ty>();
|
||||
// Check types:
|
||||
let src: &[$ty] = $src;
|
||||
let dst: &mut [u8] = $dst;
|
||||
assert_eq!(src.len() * SIZE, dst.len());
|
||||
for (src, dst) in src.iter().zip(dst.chunks_exact_mut(SIZE)) {
|
||||
dst.copy_from_slice(&src.$to_bytes());
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -1990,52 +1958,40 @@ impl ByteOrder for BigEndian {
|
|||
|
||||
#[inline]
|
||||
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
|
||||
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
|
||||
let mut out = 0u64;
|
||||
let ptr_out = &mut out as *mut u64 as *mut u8;
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
buf.as_ptr(),
|
||||
ptr_out.offset((8 - nbytes) as isize),
|
||||
nbytes,
|
||||
);
|
||||
}
|
||||
out.to_be()
|
||||
let mut out = [0; 8];
|
||||
assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len());
|
||||
let start = out.len() - nbytes;
|
||||
out[start..].copy_from_slice(&buf[..nbytes]);
|
||||
u64::from_be_bytes(out)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
|
||||
assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
|
||||
let mut out: u128 = 0;
|
||||
let ptr_out = &mut out as *mut u128 as *mut u8;
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
buf.as_ptr(),
|
||||
ptr_out.offset((16 - nbytes) as isize),
|
||||
nbytes,
|
||||
);
|
||||
}
|
||||
out.to_be()
|
||||
let mut out = [0; 16];
|
||||
assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len());
|
||||
let start = out.len() - nbytes;
|
||||
out[start..].copy_from_slice(&buf[..nbytes]);
|
||||
u128::from_be_bytes(out)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u16(buf: &mut [u8], n: u16) {
|
||||
unsafe_write_num_bytes!(u16, 2, n, buf, to_be);
|
||||
buf[..2].copy_from_slice(&n.to_be_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u32(buf: &mut [u8], n: u32) {
|
||||
unsafe_write_num_bytes!(u32, 4, n, buf, to_be);
|
||||
buf[..4].copy_from_slice(&n.to_be_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64(buf: &mut [u8], n: u64) {
|
||||
unsafe_write_num_bytes!(u64, 8, n, buf, to_be);
|
||||
buf[..8].copy_from_slice(&n.to_be_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u128(buf: &mut [u8], n: u128) {
|
||||
unsafe_write_num_bytes!(u128, 16, n, buf, to_be);
|
||||
buf[..16].copy_from_slice(&n.to_be_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2068,58 +2024,42 @@ impl ByteOrder for BigEndian {
|
|||
|
||||
#[inline]
|
||||
fn read_u16_into(src: &[u8], dst: &mut [u16]) {
|
||||
unsafe_read_slice!(src, dst, 2, to_be);
|
||||
read_slice!(src, dst, u16, from_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u32_into(src: &[u8], dst: &mut [u32]) {
|
||||
unsafe_read_slice!(src, dst, 4, to_be);
|
||||
read_slice!(src, dst, u32, from_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u64_into(src: &[u8], dst: &mut [u64]) {
|
||||
unsafe_read_slice!(src, dst, 8, to_be);
|
||||
read_slice!(src, dst, u64, from_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u128_into(src: &[u8], dst: &mut [u128]) {
|
||||
unsafe_read_slice!(src, dst, 16, to_be);
|
||||
read_slice!(src, dst, u128, from_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u16_into(src: &[u16], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "big") {
|
||||
unsafe_write_slice_native!(src, dst, u16);
|
||||
} else {
|
||||
write_slice!(src, dst, u16, 2, Self::write_u16);
|
||||
}
|
||||
write_slice!(src, dst, u16, to_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u32_into(src: &[u32], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "big") {
|
||||
unsafe_write_slice_native!(src, dst, u32);
|
||||
} else {
|
||||
write_slice!(src, dst, u32, 4, Self::write_u32);
|
||||
}
|
||||
write_slice!(src, dst, u32, to_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64_into(src: &[u64], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "big") {
|
||||
unsafe_write_slice_native!(src, dst, u64);
|
||||
} else {
|
||||
write_slice!(src, dst, u64, 8, Self::write_u64);
|
||||
}
|
||||
write_slice!(src, dst, u64, to_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u128_into(src: &[u128], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "big") {
|
||||
unsafe_write_slice_native!(src, dst, u128);
|
||||
} else {
|
||||
write_slice!(src, dst, u128, 16, Self::write_u128);
|
||||
}
|
||||
write_slice!(src, dst, u128, to_be_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2206,44 +2146,38 @@ impl ByteOrder for LittleEndian {
|
|||
|
||||
#[inline]
|
||||
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
|
||||
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
|
||||
let mut out = 0u64;
|
||||
let ptr_out = &mut out as *mut u64 as *mut u8;
|
||||
unsafe {
|
||||
copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
|
||||
}
|
||||
out.to_le()
|
||||
let mut out = [0; 8];
|
||||
assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len());
|
||||
out[..nbytes].copy_from_slice(&buf[..nbytes]);
|
||||
u64::from_le_bytes(out)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_uint128(buf: &[u8], nbytes: usize) -> u128 {
|
||||
assert!(1 <= nbytes && nbytes <= 16 && nbytes <= buf.len());
|
||||
let mut out: u128 = 0;
|
||||
let ptr_out = &mut out as *mut u128 as *mut u8;
|
||||
unsafe {
|
||||
copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
|
||||
}
|
||||
out.to_le()
|
||||
let mut out = [0; 16];
|
||||
assert!(1 <= nbytes && nbytes <= out.len() && nbytes <= buf.len());
|
||||
out[..nbytes].copy_from_slice(&buf[..nbytes]);
|
||||
u128::from_le_bytes(out)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u16(buf: &mut [u8], n: u16) {
|
||||
unsafe_write_num_bytes!(u16, 2, n, buf, to_le);
|
||||
buf[..2].copy_from_slice(&n.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u32(buf: &mut [u8], n: u32) {
|
||||
unsafe_write_num_bytes!(u32, 4, n, buf, to_le);
|
||||
buf[..4].copy_from_slice(&n.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64(buf: &mut [u8], n: u64) {
|
||||
unsafe_write_num_bytes!(u64, 8, n, buf, to_le);
|
||||
buf[..8].copy_from_slice(&n.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u128(buf: &mut [u8], n: u128) {
|
||||
unsafe_write_num_bytes!(u128, 16, n, buf, to_le);
|
||||
buf[..16].copy_from_slice(&n.to_le_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2268,58 +2202,42 @@ impl ByteOrder for LittleEndian {
|
|||
|
||||
#[inline]
|
||||
fn read_u16_into(src: &[u8], dst: &mut [u16]) {
|
||||
unsafe_read_slice!(src, dst, 2, to_le);
|
||||
read_slice!(src, dst, u16, from_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u32_into(src: &[u8], dst: &mut [u32]) {
|
||||
unsafe_read_slice!(src, dst, 4, to_le);
|
||||
read_slice!(src, dst, u32, from_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u64_into(src: &[u8], dst: &mut [u64]) {
|
||||
unsafe_read_slice!(src, dst, 8, to_le);
|
||||
read_slice!(src, dst, u64, from_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u128_into(src: &[u8], dst: &mut [u128]) {
|
||||
unsafe_read_slice!(src, dst, 16, to_le);
|
||||
read_slice!(src, dst, u128, from_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u16_into(src: &[u16], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "little") {
|
||||
unsafe_write_slice_native!(src, dst, u16);
|
||||
} else {
|
||||
write_slice!(src, dst, u16, 2, Self::write_u16);
|
||||
}
|
||||
write_slice!(src, dst, u16, to_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u32_into(src: &[u32], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "little") {
|
||||
unsafe_write_slice_native!(src, dst, u32);
|
||||
} else {
|
||||
write_slice!(src, dst, u32, 4, Self::write_u32);
|
||||
}
|
||||
write_slice!(src, dst, u32, to_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64_into(src: &[u64], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "little") {
|
||||
unsafe_write_slice_native!(src, dst, u64);
|
||||
} else {
|
||||
write_slice!(src, dst, u64, 8, Self::write_u64);
|
||||
}
|
||||
write_slice!(src, dst, u64, to_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u128_into(src: &[u128], dst: &mut [u8]) {
|
||||
if cfg!(target_endian = "little") {
|
||||
unsafe_write_slice_native!(src, dst, u128);
|
||||
} else {
|
||||
write_slice!(src, dst, u128, 16, Self::write_u128);
|
||||
}
|
||||
write_slice!(src, dst, u128, to_le_bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -2449,6 +2367,7 @@ mod test {
|
|||
macro_rules! qc_byte_order {
|
||||
($name:ident, $ty_int:ty, $max:expr,
|
||||
$bytes:expr, $read:ident, $write:ident) => {
|
||||
#[cfg(not(miri))]
|
||||
mod $name {
|
||||
#[allow(unused_imports)]
|
||||
use super::{qc_sized, Wi128};
|
||||
|
@ -2489,6 +2408,7 @@ mod test {
|
|||
};
|
||||
($name:ident, $ty_int:ty, $max:expr,
|
||||
$read:ident, $write:ident) => {
|
||||
#[cfg(not(miri))]
|
||||
mod $name {
|
||||
#[allow(unused_imports)]
|
||||
use super::{qc_sized, Wi128};
|
||||
|
@ -3405,6 +3325,7 @@ mod stdtests {
|
|||
macro_rules! qc_bytes_ext {
|
||||
($name:ident, $ty_int:ty, $max:expr,
|
||||
$bytes:expr, $read:ident, $write:ident) => {
|
||||
#[cfg(not(miri))]
|
||||
mod $name {
|
||||
#[allow(unused_imports)]
|
||||
use crate::test::{qc_sized, Wi128};
|
||||
|
@ -3455,6 +3376,7 @@ mod stdtests {
|
|||
}
|
||||
};
|
||||
($name:ident, $ty_int:ty, $max:expr, $read:ident, $write:ident) => {
|
||||
#[cfg(not(miri))]
|
||||
mod $name {
|
||||
#[allow(unused_imports)]
|
||||
use crate::test::{qc_sized, Wi128};
|
||||
|
@ -3951,6 +3873,7 @@ mod stdtests {
|
|||
// Test slice serialization/deserialization.
|
||||
macro_rules! qc_slice {
|
||||
($name:ident, $ty_int:ty, $read:ident, $write:ident, $zero:expr) => {
|
||||
#[cfg(not(miri))]
|
||||
mod $name {
|
||||
use super::qc_unsized;
|
||||
#[allow(unused_imports)]
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"fe1a0dc50ac5c7bdd60591f6d1027072c68dcf142131945f782169c74b9e8188","Cargo.toml":"5506345251dee6e156a3d0072d2b3b6bc6894d8cf91adb85fefe211741e7c7f9","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"e5858de17fc28ec7a3a62cbefedd301ace8a85291d0aad5cb416824d1b5abadd","SECURITY.md":"816ea79f8c7937888ab5a972a1efb270c4bada028b448953a195359fe11d526e","benches/buffer.rs":"242f56eaeecd1d0a0f6f9419d1bf312b8d211215355022bd4aef5e5e0f53e2a5","src/3ds.rs":"e41b653723740ed89fa68f495b64125786e8dec002e3556d164c5795db62ea50","src/apple-other.rs":"3ff0abc72786a2ac063cdc5df4d18cc53dc493cd68fcb33734cf40cfdbb8f644","src/bsd_arandom.rs":"cfa0627a6b4d1f37065d415972ab813bf1c9f43979d2ff9440c92a53868123aa","src/custom.rs":"a256bd6e7e9bb560803f23a36bd437859ea8a9d8ec92608930b94b33e7314c64","src/dragonfly.rs":"047008e742a7a8050e61ed9626b9f4146dfaa0675e11d6f3680eb8af498d9a6d","src/emscripten.rs":"e0b3b44b52f54454ec3e0a9e7c5222003369d9d1575cc0652e3e7cbe1b3b6da7","src/error.rs":"ff09a7e02d7aff3e45eca6bbef6c686cc46f3c2371a0897a856e4dec4b942e46","src/error_impls.rs":"9c34832ebb99cd5e31bc5c8ffc5beb5b3fa6f7ff0226aaa1cdf8e10e6d64b324","src/espidf.rs":"915ca14cbf9299de51a3c67f34fdd252461d6545f33a7232dfb7fa247ccc0209","src/fuchsia.rs":"d307b15db9f2d67b43050ae6027779a6eb2b8a69e1e89931b55b767aa2622250","src/hermit.rs":"18fdd7917c73f8b16aa82b18003948d32f9b314da10e16ef9cd2fa077b17af00","src/hurd.rs":"1053908c4eaeae9e44078c9509aa80268caa1d66642b7c6a9a80f5b9f0e63fb0","src/js.rs":"c4cd60bcfe63f8affe947773197e288536ab205a73001059f39fc2e5688e98b6","src/lib.rs":"178b4b1dae3a41721f365ea5a4eda3f5b936b310afa4431935968e96edac3120","src/linux_android.rs":"e5f9e579bbde254fcab8f6b79b893d6b74054e023b21c56a3b2b21d8f4b4d825","src/macos.rs":"8f51e095906e751b68e837bfc63cc02b243e1698b66353566ccba507c81ddad3","src/openbsd.rs":"f6fd0aa74f704335a7e0532bf5e61a7ca90b0cbc398a9c01a0fd891b6fabca0c","src/rdrand.rs":"846ac7b8380a05a50e0592dca57338beb1634c0efc878d6d1e9421be3469a744","src/solaris_illumos.rs":"7209c8b1172fc4df5ad8a79f165556b403cdd90b9eb5f7f7f9ec97bf06f4d8d7","src/solid.rs":"58919109faf06e6d546f75f785d78d6c055e1f95110d1791d9191d1e404f1e20","src/use_file.rs":"ecfc1011b4a9c962ae9b4b75ca5149a4ee83cb0951a80224ce5417046ce11717","src/util.rs":"580fb7c4e41eb6007def8626e019829c22a63980fa4da68a1adef687c57953a2","src/util_libc.rs":"48c1fe251958c6c57b7c93d83f3648d97034feeee0d5cda0cbe7bc0ee0a73fca","src/vita.rs":"ecfa9d347ad5c480ba8ff80a9de968ae060ffb435f1e95777ee413642e62e50a","src/vxworks.rs":"984726b6dd9638a38ceda83124683419b9d69a9041ad9117a470eaec5b386ce4","src/wasi.rs":"229a58af3f13a629571fb83a0c11ef0ed696ba7a44ee2e811c9f348a19b2fb69","src/windows.rs":"dd3d833979fb6b96c04b84dbf8461d5fc819bde93ad9dc26bd0f6c282656c733","tests/common/mod.rs":"b9a36043d71963ba43a9e2899ba8eea80ff9f3284d243d9b9b9f941afa4f4aa4","tests/custom.rs":"1e944ae523b62dba53fe3daf1b964a2498c8fdd21dfa7afe53781bff2fcf276e","tests/normal.rs":"9e1c4b1e468a09ed0225370dfb6608f8b8135e0fabb09bbc1a718105164aade6","tests/rdrand.rs":"156676b57f1e6bd4d66d85b8a999f1cf7a8fb749a10b8b2b4dbbcf803e8c4cd3"},"package":"fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"}
|
||||
{"files":{"CHANGELOG.md":"d77ff9f599c3e313723df758f861e23f3caa696d0b8595af2975c2cc5be0f254","Cargo.toml":"822356b05121dcc6f3ec20d99814a93c9511e2bb3612266214e2e94fe844e9c3","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"42fa16951ce7f24b5a467a40e5b449a1d41e662f97ca779864f053f39e097737","README.md":"543f0efa922ff55d3cdc1c96a188dff669f57a2ff3b7dfa0c95368b8e646b5dd","SECURITY.md":"816ea79f8c7937888ab5a972a1efb270c4bada028b448953a195359fe11d526e","benches/buffer.rs":"242f56eaeecd1d0a0f6f9419d1bf312b8d211215355022bd4aef5e5e0f53e2a5","src/3ds.rs":"dae5b84328b063a3750a67e5086db530b905a661b152181f0d6b4d63e72b70e2","src/apple-other.rs":"75f2c3319068e06ec27135d516953ab645cc7c45033f045cba44136236ef5601","src/bsd_arandom.rs":"2ace9473afc3df95594884d87d8f484cf141c9d01f2c22ece2bb1118b73d51bb","src/custom.rs":"ae5dc94bc12a4a284762e99891b013c509942b1a802ea559e04e572ed44479dc","src/dragonfly.rs":"4cffb7af2b62d515f28790b906f0293b44af1d75b23c87fa9e50d5ef99bfa02c","src/emscripten.rs":"e0b3b44b52f54454ec3e0a9e7c5222003369d9d1575cc0652e3e7cbe1b3b6da7","src/error.rs":"ab5b82ddb8304e8ad75d905d7dc5ba8deec92096930e81e87d7a28f3da382dee","src/error_impls.rs":"4c068e81d876237a7e0a0e91519896bd670c2f999ca729f7fb970caf888cab46","src/espidf.rs":"50f70136fe46f9fe9a728aa7881cdc8144f430620168cf42519c2666a8edc11f","src/fuchsia.rs":"535ed84250cfe8f176494eba226d1c1df9687b5c30cf52d5949f56a591947656","src/hermit.rs":"c9d9d5c78e0e435c2678ef43d1296aef885fd62957d6b454d758ca475cd4e544","src/hurd.rs":"c0f807d7cc4ae6a5e0b1800bbd76639270503596c8f3cade2e59bf62e0bc7a89","src/js.rs":"4306b7a49441e0da2a0737f92f56d3258ddcd1566ec3aea4a4f4a865bbf0ff87","src/lazy.rs":"21764d7cffe5177a331ec37758cc550c6e3be8c5f6fdfb7606053dafbe6a994b","src/lib.rs":"085e7246d863322ef2031b8c6ac40245c77ce3cb0cc71ac5e0c102d188080780","src/linux_android.rs":"92c71e68adcb9bc4ee39e6b2db730e06af1e0c8db0389712b5ea8a1d86991277","src/linux_android_with_fallback.rs":"620577d889d92916aeed62ac0e4f711725fddb7e7bb331f02474160104354e8e","src/macos.rs":"6e4f8377c7ad3c5dea1816a7bac22a3bb5ba85260aee71d027e32cd6602cb2dd","src/openbsd.rs":"f22ffe151d1797785c32e165459e15a34643f8a441c12da736e8a22d7103db6e","src/rdrand.rs":"ffbe1bfb8f5b30a95f462fa85db07e251f63248c6c0daf3b5f586034cedfa976","src/solaris_illumos.rs":"2f0d03956d042249aed1c2f02fc9ad389ab4dcd1dfe5c5e7c189830545497259","src/solid.rs":"a5a6e4b2b43400548b36035b9a513e70ec17809d521757e7228d2214352d24ed","src/use_file.rs":"1d7cf9370697ae69d29792d0a50ae972b093676536eb0529d9a801efbecbb096","src/util.rs":"e2c1b86ea97ca5c61d562182890cbe24c7eaa37ff8945c17fcfa665b767da1b0","src/util_libc.rs":"9321ac241c1e2088e7a73d3323a79076f5d9253cf2f077ea7083be86ee313469","src/vita.rs":"97dc7ddd706c0c64273cc5b2a6c9cab47c221921908809a9f9a8b72a1753ce90","src/vxworks.rs":"3c132cd52df3a8cf903f430ce90d3432c4b4bb99bf069f5546dee43f4f10a555","src/wasi.rs":"45b95d98766cfdc0495cfe5da6c3b63e99dda34c334deee779cf146a29350344","src/windows.rs":"7e3e73fb29a7e2748d32344d1bb9327603c6d78eb0fc5e62f50c6fa93b648c60","tests/common/mod.rs":"b9a36043d71963ba43a9e2899ba8eea80ff9f3284d243d9b9b9f941afa4f4aa4","tests/custom.rs":"1e944ae523b62dba53fe3daf1b964a2498c8fdd21dfa7afe53781bff2fcf276e","tests/normal.rs":"9e1c4b1e468a09ed0225370dfb6608f8b8135e0fabb09bbc1a718105164aade6","tests/rdrand.rs":"fcf3f78e3078e1b262d0efae8f3c4a730f3fbf68df656fceb78e22ee4cc98990"},"package":"94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"}
|
|
@ -4,6 +4,42 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.2.14] - 2024-04-08
|
||||
### Fixed
|
||||
- Enable `/dev/urandom` fallback for MUSL-based Linux targets [#408]
|
||||
|
||||
[#408]: https://github.com/rust-random/getrandom/pull/408
|
||||
|
||||
## [0.2.13] - 2024-04-06
|
||||
### Added
|
||||
- `linux_disable_fallback` crate feature to disable `/dev/urandom`-based fallback on Linux and
|
||||
Android targets. Enabling this feature bumps minimum supported Linux kernel version to 3.17 and
|
||||
Android API level to 23 (Marshmallow). [#396]
|
||||
|
||||
### Changed
|
||||
- Disable `/dev/urandom` fallback for Linux targets outside of the following `target_arch`es:
|
||||
`aarch64`, `arm`, `powerpc`, `powerpc64`, `s390x`, `x86`, `x86_64` [#396]
|
||||
- Do not catch `EPERM` error code on Android while checking availability of
|
||||
the `getrandom` syscall [#396]
|
||||
|
||||
[#396]: https://github.com/rust-random/getrandom/pull/396
|
||||
|
||||
## [0.2.12] - 2024-01-09
|
||||
### Fixed
|
||||
- Custom backend for targets without atomics [#385]
|
||||
|
||||
### Changed
|
||||
- Improve robustness of the Hermit backend and `sys_fill_exact` [#386]
|
||||
- Raise minimum supported Apple OS versions to macOS 10.12 and iOS 10 [#388]
|
||||
|
||||
### Added
|
||||
- Document platform support policy [#387]
|
||||
|
||||
[#385]: https://github.com/rust-random/getrandom/pull/385
|
||||
[#386]: https://github.com/rust-random/getrandom/pull/386
|
||||
[#387]: https://github.com/rust-random/getrandom/pull/387
|
||||
[#388]: https://github.com/rust-random/getrandom/pull/388
|
||||
|
||||
## [0.2.11] - 2023-11-08
|
||||
### Added
|
||||
- GNU/Hurd support [#370]
|
||||
|
@ -403,6 +439,9 @@ Publish initial implementation.
|
|||
## [0.0.0] - 2019-01-19
|
||||
Publish an empty template library.
|
||||
|
||||
[0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14
|
||||
[0.2.13]: https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.13
|
||||
[0.2.12]: https://github.com/rust-random/getrandom/compare/v0.2.11...v0.2.12
|
||||
[0.2.11]: https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11
|
||||
[0.2.10]: https://github.com/rust-random/getrandom/compare/v0.2.9...v0.2.10
|
||||
[0.2.9]: https://github.com/rust-random/getrandom/compare/v0.2.8...v0.2.9
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
version = "0.2.14"
|
||||
authors = ["The Rand Project Developers"]
|
||||
exclude = [".*"]
|
||||
description = "A small cross-platform library for retrieving random data from system source"
|
||||
|
@ -63,6 +63,7 @@ js = [
|
|||
"wasm-bindgen",
|
||||
"js-sys",
|
||||
]
|
||||
linux_disable_fallback = []
|
||||
rdrand = []
|
||||
rustc-dep-of-std = [
|
||||
"compiler_builtins",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright 2018 Developers of the Rand project
|
||||
Copyright (c) 2018-2024 The rust-random Project Developers
|
||||
Copyright (c) 2014 The Rust Project Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
|
|
|
@ -54,11 +54,28 @@ crate features, WASM support and Custom RNGs see the
|
|||
|
||||
This crate requires Rust 1.36.0 or later.
|
||||
|
||||
# License
|
||||
## Platform Support
|
||||
|
||||
This crate generally supports the same operating system and platform versions that the Rust standard library does.
|
||||
Additional targets may be supported using pluggable custom implementations.
|
||||
|
||||
This means that as Rust drops support for old versions of operating systems (such as old Linux kernel versions, Android API levels, etc)
|
||||
in stable releases, `getrandom` may create new patch releases (`0.N.x`) that remove support for outdated platform versions.
|
||||
|
||||
## License
|
||||
|
||||
The `getrandom` library is distributed under either of
|
||||
|
||||
* [Apache License, Version 2.0](LICENSE-APACHE)
|
||||
* [MIT license](LICENSE-MIT)
|
||||
* [Apache License, Version 2.0][LICENSE-APACHE]
|
||||
* [MIT license][LICENSE-MIT]
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
|
||||
[LICENSE-APACHE]: https://github.com/rust-random/getrandom/blob/master/LICENSE-APACHE
|
||||
[LICENSE-MIT]: https://github.com/rust-random/getrandom/blob/master/LICENSE-MIT
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for Nintendo 3DS
|
||||
use crate::util_libc::sys_fill_exact;
|
||||
use crate::Error;
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for iOS
|
||||
//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable.
|
||||
use crate::Error;
|
||||
use core::{ffi::c_void, mem::MaybeUninit, ptr::null};
|
||||
use core::{ffi::c_void, mem::MaybeUninit};
|
||||
|
||||
#[link(name = "Security", kind = "framework")]
|
||||
// libsystem contains the libc of Darwin, and every binary ends up linked against it either way. This
|
||||
// makes it a more lightweight choice compared to `Security.framework`.
|
||||
extern "C" {
|
||||
fn SecRandomCopyBytes(rnd: *const c_void, count: usize, bytes: *mut u8) -> i32;
|
||||
// This RNG uses a thread-local CSPRNG to provide data, which is seeded by the operating system's root CSPRNG.
|
||||
// Its the best option after `getentropy` on modern Darwin-based platforms that also avoids the
|
||||
// high startup costs and linking of Security.framework.
|
||||
//
|
||||
// While its just an implementation detail, `Security.framework` just calls into this anyway.
|
||||
fn CCRandomGenerateBytes(bytes: *mut c_void, size: usize) -> i32;
|
||||
}
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
// Apple's documentation guarantees kSecRandomDefault is a synonym for NULL.
|
||||
let ret = unsafe { SecRandomCopyBytes(null(), dest.len(), dest.as_mut_ptr() as *mut u8) };
|
||||
// errSecSuccess (from SecBase.h) is always zero.
|
||||
let ret = unsafe { CCRandomGenerateBytes(dest.as_mut_ptr() as *mut c_void, dest.len()) };
|
||||
// kCCSuccess (from CommonCryptoError.h) is always zero.
|
||||
if ret != 0 {
|
||||
Err(Error::IOS_SEC_RANDOM)
|
||||
} else {
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for FreeBSD and NetBSD
|
||||
use crate::{
|
||||
util_libc::{sys_fill_exact, Weak},
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! An implementation which calls out to an externally defined function.
|
||||
use crate::{util::uninit_slice_fill_zero, Error};
|
||||
use core::{mem::MaybeUninit, num::NonZeroU32};
|
||||
|
@ -73,7 +65,6 @@ use core::{mem::MaybeUninit, num::NonZeroU32};
|
|||
/// [top-level documentation](index.html#custom-implementations) this
|
||||
/// registration only has an effect on unsupported targets.
|
||||
#[macro_export]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "custom")))]
|
||||
macro_rules! register_custom_getrandom {
|
||||
($path:path) => {
|
||||
// TODO(MSRV 1.37): change to unnamed block
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for DragonFly BSD
|
||||
use crate::{
|
||||
use_file,
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
use core::{fmt, num::NonZeroU32};
|
||||
|
||||
/// A small and `no_std` compatible error type
|
||||
|
@ -35,7 +28,11 @@ impl Error {
|
|||
pub const UNSUPPORTED: Error = internal_error(0);
|
||||
/// The platform-specific `errno` returned a non-positive value.
|
||||
pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
|
||||
/// Call to iOS [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes) failed.
|
||||
/// Encountered an unexpected situation which should not happen in practice.
|
||||
pub const UNEXPECTED: Error = internal_error(2);
|
||||
/// Call to [`CCRandomGenerateBytes`](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) failed
|
||||
/// on iOS, tvOS, or waatchOS.
|
||||
// TODO: Update this constant name in the next breaking release.
|
||||
pub const IOS_SEC_RANDOM: Error = internal_error(3);
|
||||
/// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
|
||||
pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);
|
||||
|
@ -164,6 +161,7 @@ fn internal_desc(error: Error) -> Option<&'static str> {
|
|||
match error {
|
||||
Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
|
||||
Error::ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
|
||||
Error::UNEXPECTED => Some("unexpected situation"),
|
||||
Error::IOS_SEC_RANDOM => Some("SecRandomCopyBytes: iOS Security framework failure"),
|
||||
Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
|
||||
Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
extern crate std;
|
||||
|
||||
use crate::Error;
|
||||
use core::convert::From;
|
||||
use std::io;
|
||||
|
||||
impl From<Error> for io::Error {
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for ESP-IDF
|
||||
use crate::Error;
|
||||
use core::{ffi::c_void, mem::MaybeUninit};
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for Fuchsia Zircon
|
||||
use crate::Error;
|
||||
use core::mem::MaybeUninit;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
//! Implementation for Hermit
|
||||
use crate::Error;
|
||||
use core::{cmp::min, mem::MaybeUninit, num::NonZeroU32};
|
||||
use core::{mem::MaybeUninit, num::NonZeroU32};
|
||||
|
||||
/// Minimum return value which we should get from syscalls in practice,
|
||||
/// because Hermit uses positive `i32`s for error codes:
|
||||
/// https://github.com/hermitcore/libhermit-rs/blob/main/src/errno.rs
|
||||
const MIN_RET_CODE: isize = -(i32::MAX as isize);
|
||||
|
||||
extern "C" {
|
||||
fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;
|
||||
|
@ -8,14 +14,16 @@ extern "C" {
|
|||
pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
while !dest.is_empty() {
|
||||
let res = unsafe { sys_read_entropy(dest.as_mut_ptr() as *mut u8, dest.len(), 0) };
|
||||
if res < 0 {
|
||||
// SAFETY: all Hermit error codes use i32 under the hood:
|
||||
// https://github.com/hermitcore/libhermit-rs/blob/master/src/errno.rs
|
||||
let code = unsafe { NonZeroU32::new_unchecked((-res) as u32) };
|
||||
return Err(code.into());
|
||||
// Positive `isize`s can be safely casted to `usize`
|
||||
if res > 0 && (res as usize) <= dest.len() {
|
||||
dest = &mut dest[res as usize..];
|
||||
} else {
|
||||
let err = match res {
|
||||
MIN_RET_CODE..=-1 => NonZeroU32::new(-res as u32).unwrap().into(),
|
||||
_ => Error::UNEXPECTED,
|
||||
};
|
||||
return Err(err);
|
||||
}
|
||||
let len = min(res as usize, dest.len());
|
||||
dest = &mut dest[len..];
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for GNU/Hurd
|
||||
use crate::util_libc::sys_fill_exact;
|
||||
use crate::Error;
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//! Implementation for WASM based on Web and Node.js
|
||||
use crate::Error;
|
||||
|
||||
extern crate std;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
|
||||
// This structure represents a lazily initialized static usize value. Useful
|
||||
// when it is preferable to just rerun initialization instead of locking.
|
||||
// unsync_init will invoke an init() function until it succeeds, then return the
|
||||
// cached value for future calls.
|
||||
//
|
||||
// unsync_init supports init() "failing". If the init() method returns UNINIT,
|
||||
// that value will be returned as normal, but will not be cached.
|
||||
//
|
||||
// Users should only depend on the _value_ returned by init() functions.
|
||||
// Specifically, for the following init() function:
|
||||
// fn init() -> usize {
|
||||
// a();
|
||||
// let v = b();
|
||||
// c();
|
||||
// v
|
||||
// }
|
||||
// the effects of c() or writes to shared memory will not necessarily be
|
||||
// observed and additional synchronization methods may be needed.
|
||||
pub(crate) struct LazyUsize(AtomicUsize);
|
||||
|
||||
impl LazyUsize {
|
||||
pub const fn new() -> Self {
|
||||
Self(AtomicUsize::new(Self::UNINIT))
|
||||
}
|
||||
|
||||
// The initialization is not completed.
|
||||
pub const UNINIT: usize = usize::max_value();
|
||||
|
||||
// Runs the init() function at most once, returning the value of some run of
|
||||
// init(). Multiple callers can run their init() functions in parallel.
|
||||
// init() should always return the same value, if it succeeds.
|
||||
pub fn unsync_init(&self, init: impl FnOnce() -> usize) -> usize {
|
||||
// Relaxed ordering is fine, as we only have a single atomic variable.
|
||||
let mut val = self.0.load(Relaxed);
|
||||
if val == Self::UNINIT {
|
||||
val = init();
|
||||
self.0.store(val, Relaxed);
|
||||
}
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
// Identical to LazyUsize except with bool instead of usize.
|
||||
pub(crate) struct LazyBool(LazyUsize);
|
||||
|
||||
impl LazyBool {
|
||||
pub const fn new() -> Self {
|
||||
Self(LazyUsize::new())
|
||||
}
|
||||
|
||||
pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {
|
||||
self.0.unsync_init(|| init() as usize) != 0
|
||||
}
|
||||
}
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2019 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Interface to the operating system's random number generator.
|
||||
//!
|
||||
//! # Supported targets
|
||||
|
@ -14,8 +6,8 @@
|
|||
//! | ----------------- | ------------------ | --------------
|
||||
//! | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
|
||||
//! | Windows | `*‑windows‑*` | [`BCryptGenRandom`]
|
||||
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3] if available, otherwise [`/dev/urandom`][4] (identical to `/dev/random`)
|
||||
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`SecRandomCopyBytes`]
|
||||
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3]
|
||||
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`CCRandomGenerateBytes`]
|
||||
//! | FreeBSD | `*‑freebsd` | [`getrandom`][5] if available, otherwise [`kern.arandom`][6]
|
||||
//! | OpenBSD | `*‑openbsd` | [`getentropy`][7]
|
||||
//! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
|
||||
|
@ -55,6 +47,21 @@
|
|||
//! This prevents a crate from overriding a secure source of randomness
|
||||
//! (either accidentally or intentionally).
|
||||
//!
|
||||
//! ## `/dev/urandom` fallback on Linux and Android
|
||||
//!
|
||||
//! On Linux targets the fallback is present only if either `target_env` is `musl`,
|
||||
//! or `target_arch` is one of the following: `aarch64`, `arm`, `powerpc`, `powerpc64`,
|
||||
//! `s390x`, `x86`, `x86_64`. Other supported targets [require][platform-support]
|
||||
//! kernel versions which support `getrandom` system call, so fallback is not needed.
|
||||
//!
|
||||
//! On Android targets the fallback is present only for the following `target_arch`es:
|
||||
//! `aarch64`, `arm`, `x86`, `x86_64`. Other `target_arch`es (e.g. RISC-V) require
|
||||
//! sufficiently high API levels.
|
||||
//!
|
||||
//! The fallback can be disabled by enabling the `linux_disable_fallback` crate feature.
|
||||
//! Note that doing so will bump minimum supported Linux kernel version to 3.17 and
|
||||
//! Android API level to 23 (Marshmallow).
|
||||
//!
|
||||
//! ### RDRAND on x86
|
||||
//!
|
||||
//! *If the `rdrand` Cargo feature is enabled*, `getrandom` will fallback to using
|
||||
|
@ -106,6 +113,16 @@
|
|||
//! ```
|
||||
//! This crate will then use the provided `webcrypto` implementation.
|
||||
//!
|
||||
//! ### Platform Support
|
||||
//! This crate generally supports the same operating system and platform versions
|
||||
//! that the Rust standard library does. Additional targets may be supported using
|
||||
//! pluggable custom implementations.
|
||||
//!
|
||||
//! This means that as Rust drops support for old versions of operating systems
|
||||
//! (such as old Linux kernel versions, Android API levels, etc) in stable releases,
|
||||
//! `getrandom` may create new patch releases (`0.N.x`) that remove support for
|
||||
//! outdated platform versions.
|
||||
//!
|
||||
//! ### Custom implementations
|
||||
//!
|
||||
//! The [`register_custom_getrandom!`] macro allows a user to mark their own
|
||||
|
@ -151,8 +168,8 @@
|
|||
//! on every call to `getrandom`, hence after the first successful call one
|
||||
//! can be reasonably confident that no errors will occur.
|
||||
//!
|
||||
//! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
|
||||
//! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
|
||||
//! [1]: https://manned.org/getrandom.2
|
||||
//! [2]: https://manned.org/urandom.4
|
||||
//! [3]: https://www.unix.com/man-page/mojave/2/getentropy/
|
||||
//! [4]: https://www.unix.com/man-page/mojave/4/urandom/
|
||||
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
|
||||
|
@ -172,7 +189,7 @@
|
|||
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
|
||||
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
|
||||
//! [`RDRAND`]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
|
||||
//! [`SecRandomCopyBytes`]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
|
||||
//! [`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html
|
||||
//! [`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
|
||||
//! [`crypto.randomFillSync`]: https://nodejs.org/api/crypto.html#cryptorandomfillsyncbuffer-offset-size
|
||||
//! [`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
|
||||
|
@ -183,15 +200,16 @@
|
|||
//! [CommonJS modules]: https://nodejs.org/api/modules.html
|
||||
//! [ES modules]: https://nodejs.org/api/esm.html
|
||||
//! [`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55
|
||||
//! [platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
||||
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://docs.rs/getrandom/0.2.11"
|
||||
html_root_url = "https://docs.rs/getrandom/0.2.14"
|
||||
)]
|
||||
#![no_std]
|
||||
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
|
@ -221,9 +239,52 @@ cfg_if! {
|
|||
if #[cfg(any(target_os = "haiku", target_os = "redox", target_os = "nto", target_os = "aix"))] {
|
||||
mod util_libc;
|
||||
#[path = "use_file.rs"] mod imp;
|
||||
} else if #[cfg(any(target_os = "android", target_os = "linux"))] {
|
||||
} else if #[cfg(all(
|
||||
not(feature = "linux_disable_fallback"),
|
||||
any(
|
||||
// Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets
|
||||
// level 21 (Lollipop) [1], while `getrandom(2)` was added only in
|
||||
// level 23 (Marshmallow). Note that it applies only to the "old" `target_arch`es,
|
||||
// RISC-V Android targets sufficiently new API level, same will apply for potential
|
||||
// new Android `target_arch`es.
|
||||
// [0]: https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html
|
||||
// [1]: https://github.com/rust-lang/rust/pull/120593
|
||||
all(
|
||||
target_os = "android",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
),
|
||||
),
|
||||
// Only on these `target_arch`es Rust supports Linux kernel versions (3.2+)
|
||||
// that precede the version (3.17) in which `getrandom(2)` was added:
|
||||
// https://doc.rust-lang.org/stable/rustc/platform-support.html
|
||||
all(
|
||||
target_os = "linux",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "s390x",
|
||||
target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
// Minimum supported Linux kernel version for MUSL targets
|
||||
// is not specified explicitly (as of Rust 1.77) and they
|
||||
// are used in practice to target pre-3.17 kernels.
|
||||
target_env = "musl",
|
||||
),
|
||||
)
|
||||
),
|
||||
))] {
|
||||
mod util_libc;
|
||||
mod use_file;
|
||||
mod lazy;
|
||||
#[path = "linux_android_with_fallback.rs"] mod imp;
|
||||
} else if #[cfg(any(target_os = "android", target_os = "linux"))] {
|
||||
mod util_libc;
|
||||
#[path = "linux_android.rs"] mod imp;
|
||||
} else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
|
||||
mod util_libc;
|
||||
|
@ -242,7 +303,6 @@ cfg_if! {
|
|||
#[path = "apple-other.rs"] mod imp;
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
mod util_libc;
|
||||
mod use_file;
|
||||
#[path = "macos.rs"] mod imp;
|
||||
} else if #[cfg(target_os = "openbsd")] {
|
||||
mod util_libc;
|
||||
|
@ -272,9 +332,11 @@ cfg_if! {
|
|||
mod util_libc;
|
||||
#[path = "emscripten.rs"] mod imp;
|
||||
} else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
|
||||
mod lazy;
|
||||
#[path = "rdrand.rs"] mod imp;
|
||||
} else if #[cfg(all(feature = "rdrand",
|
||||
any(target_arch = "x86_64", target_arch = "x86")))] {
|
||||
mod lazy;
|
||||
#[path = "rdrand.rs"] mod imp;
|
||||
} else if #[cfg(all(feature = "js",
|
||||
any(target_arch = "wasm32", target_arch = "wasm64"),
|
||||
|
|
|
@ -1,48 +1,7 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for Linux / Android
|
||||
use crate::{
|
||||
util::LazyBool,
|
||||
util_libc::{last_os_error, sys_fill_exact},
|
||||
{use_file, Error},
|
||||
};
|
||||
//! Implementation for Linux / Android without `/dev/urandom` fallback
|
||||
use crate::{util_libc, Error};
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
// getrandom(2) was introduced in Linux 3.17
|
||||
static HAS_GETRANDOM: LazyBool = LazyBool::new();
|
||||
if HAS_GETRANDOM.unsync_init(is_getrandom_available) {
|
||||
sys_fill_exact(dest, |buf| unsafe {
|
||||
getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0)
|
||||
})
|
||||
} else {
|
||||
use_file::getrandom_inner(dest)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_getrandom_available() -> bool {
|
||||
let res = unsafe { getrandom(core::ptr::null_mut(), 0, libc::GRND_NONBLOCK) };
|
||||
if res < 0 {
|
||||
match last_os_error().raw_os_error() {
|
||||
Some(libc::ENOSYS) => false, // No kernel support
|
||||
Some(libc::EPERM) => false, // Blocked by seccomp
|
||||
_ => true,
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn getrandom(
|
||||
buf: *mut libc::c_void,
|
||||
buflen: libc::size_t,
|
||||
flags: libc::c_uint,
|
||||
) -> libc::ssize_t {
|
||||
libc::syscall(libc::SYS_getrandom, buf, buflen, flags) as libc::ssize_t
|
||||
util_libc::sys_fill_exact(dest, util_libc::getrandom_syscall)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
//! Implementation for Linux / Android with `/dev/urandom` fallback
|
||||
use crate::{
|
||||
lazy::LazyBool,
|
||||
util_libc::{getrandom_syscall, last_os_error, sys_fill_exact},
|
||||
{use_file, Error},
|
||||
};
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
// getrandom(2) was introduced in Linux 3.17
|
||||
static HAS_GETRANDOM: LazyBool = LazyBool::new();
|
||||
if HAS_GETRANDOM.unsync_init(is_getrandom_available) {
|
||||
sys_fill_exact(dest, getrandom_syscall)
|
||||
} else {
|
||||
use_file::getrandom_inner(dest)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_getrandom_available() -> bool {
|
||||
if getrandom_syscall(&mut []) < 0 {
|
||||
match last_os_error().raw_os_error() {
|
||||
Some(libc::ENOSYS) => false, // No kernel support
|
||||
// The fallback on EPERM is intentionally not done on Android since this workaround
|
||||
// seems to be needed only for specific Linux-based products that aren't based
|
||||
// on Android. See https://github.com/rust-random/getrandom/issues/229.
|
||||
#[cfg(target_os = "linux")]
|
||||
Some(libc::EPERM) => false, // Blocked by seccomp
|
||||
_ => true,
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -1,36 +1,18 @@
|
|||
// Copyright 2019 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for macOS
|
||||
use crate::{
|
||||
use_file,
|
||||
util_libc::{last_os_error, Weak},
|
||||
Error,
|
||||
};
|
||||
use core::mem::{self, MaybeUninit};
|
||||
use crate::{util_libc::last_os_error, Error};
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
type GetEntropyFn = unsafe extern "C" fn(*mut u8, libc::size_t) -> libc::c_int;
|
||||
extern "C" {
|
||||
// Supported as of macOS 10.12+.
|
||||
fn getentropy(buf: *mut u8, size: libc::size_t) -> libc::c_int;
|
||||
}
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
// getentropy(2) was added in 10.12, Rust supports 10.7+
|
||||
static GETENTROPY: Weak = unsafe { Weak::new("getentropy\0") };
|
||||
if let Some(fptr) = GETENTROPY.ptr() {
|
||||
let func: GetEntropyFn = unsafe { mem::transmute(fptr) };
|
||||
for chunk in dest.chunks_mut(256) {
|
||||
let ret = unsafe { func(chunk.as_mut_ptr() as *mut u8, chunk.len()) };
|
||||
if ret != 0 {
|
||||
return Err(last_os_error());
|
||||
}
|
||||
for chunk in dest.chunks_mut(256) {
|
||||
let ret = unsafe { getentropy(chunk.as_mut_ptr() as *mut u8, chunk.len()) };
|
||||
if ret != 0 {
|
||||
return Err(last_os_error());
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
// We fallback to reading from /dev/random instead of SecRandomCopyBytes
|
||||
// to avoid high startup costs and linking the Security framework.
|
||||
use_file::getrandom_inner(dest)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for OpenBSD
|
||||
use crate::{util_libc::last_os_error, Error};
|
||||
use core::mem::MaybeUninit;
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
use crate::{
|
||||
util::{slice_as_uninit, LazyBool},
|
||||
Error,
|
||||
};
|
||||
//! RDRAND backend for x86(-64) targets
|
||||
use crate::{lazy::LazyBool, util::slice_as_uninit, Error};
|
||||
use core::mem::{size_of, MaybeUninit};
|
||||
|
||||
cfg_if! {
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for the Solaris family
|
||||
//!
|
||||
//! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A.
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for SOLID
|
||||
use crate::Error;
|
||||
use core::{mem::MaybeUninit, num::NonZeroU32};
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementations that just need to read from a file
|
||||
use crate::{
|
||||
util::LazyUsize,
|
||||
util_libc::{open_readonly, sys_fill_exact},
|
||||
Error,
|
||||
};
|
||||
|
@ -21,7 +12,7 @@ use core::{
|
|||
// We prefer using /dev/urandom and only use /dev/random if the OS
|
||||
// documentation indicates that /dev/urandom is insecure.
|
||||
// On Solaris/Illumos, see src/solaris_illumos.rs
|
||||
// On Dragonfly, Haiku, macOS, and QNX Neutrino the devices are identical.
|
||||
// On Dragonfly, Haiku, and QNX Neutrino the devices are identical.
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
const FILE_PATH: &str = "/dev/random\0";
|
||||
#[cfg(any(
|
||||
|
@ -31,10 +22,10 @@ const FILE_PATH: &str = "/dev/random\0";
|
|||
target_os = "redox",
|
||||
target_os = "dragonfly",
|
||||
target_os = "haiku",
|
||||
target_os = "macos",
|
||||
target_os = "nto",
|
||||
))]
|
||||
const FILE_PATH: &str = "/dev/urandom\0";
|
||||
const FD_UNINIT: usize = usize::max_value();
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
let fd = get_rng_fd()?;
|
||||
|
@ -47,10 +38,10 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
|||
// bytes. The file will be opened exactly once. All subsequent calls will
|
||||
// return the same file descriptor. This file descriptor is never closed.
|
||||
fn get_rng_fd() -> Result<libc::c_int, Error> {
|
||||
static FD: AtomicUsize = AtomicUsize::new(LazyUsize::UNINIT);
|
||||
static FD: AtomicUsize = AtomicUsize::new(FD_UNINIT);
|
||||
fn get_fd() -> Option<libc::c_int> {
|
||||
match FD.load(Relaxed) {
|
||||
LazyUsize::UNINIT => None,
|
||||
FD_UNINIT => None,
|
||||
val => Some(val as libc::c_int),
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +66,8 @@ fn get_rng_fd() -> Result<libc::c_int, Error> {
|
|||
wait_until_rng_ready()?;
|
||||
|
||||
let fd = unsafe { open_readonly(FILE_PATH)? };
|
||||
// The fd always fits in a usize without conflicting with UNINIT.
|
||||
debug_assert!(fd >= 0 && (fd as usize) < LazyUsize::UNINIT);
|
||||
// The fd always fits in a usize without conflicting with FD_UNINIT.
|
||||
debug_assert!(fd >= 0 && (fd as usize) < FD_UNINIT);
|
||||
FD.store(fd as usize, Relaxed);
|
||||
|
||||
Ok(fd)
|
||||
|
|
|
@ -1,71 +1,5 @@
|
|||
// Copyright 2019 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![allow(dead_code)]
|
||||
use core::{
|
||||
mem::MaybeUninit,
|
||||
ptr,
|
||||
sync::atomic::{AtomicUsize, Ordering::Relaxed},
|
||||
};
|
||||
|
||||
// This structure represents a lazily initialized static usize value. Useful
|
||||
// when it is preferable to just rerun initialization instead of locking.
|
||||
// Both unsync_init and sync_init will invoke an init() function until it
|
||||
// succeeds, then return the cached value for future calls.
|
||||
//
|
||||
// Both methods support init() "failing". If the init() method returns UNINIT,
|
||||
// that value will be returned as normal, but will not be cached.
|
||||
//
|
||||
// Users should only depend on the _value_ returned by init() functions.
|
||||
// Specifically, for the following init() function:
|
||||
// fn init() -> usize {
|
||||
// a();
|
||||
// let v = b();
|
||||
// c();
|
||||
// v
|
||||
// }
|
||||
// the effects of c() or writes to shared memory will not necessarily be
|
||||
// observed and additional synchronization methods with be needed.
|
||||
pub struct LazyUsize(AtomicUsize);
|
||||
|
||||
impl LazyUsize {
|
||||
pub const fn new() -> Self {
|
||||
Self(AtomicUsize::new(Self::UNINIT))
|
||||
}
|
||||
|
||||
// The initialization is not completed.
|
||||
pub const UNINIT: usize = usize::max_value();
|
||||
|
||||
// Runs the init() function at least once, returning the value of some run
|
||||
// of init(). Multiple callers can run their init() functions in parallel.
|
||||
// init() should always return the same value, if it succeeds.
|
||||
pub fn unsync_init(&self, init: impl FnOnce() -> usize) -> usize {
|
||||
// Relaxed ordering is fine, as we only have a single atomic variable.
|
||||
let mut val = self.0.load(Relaxed);
|
||||
if val == Self::UNINIT {
|
||||
val = init();
|
||||
self.0.store(val, Relaxed);
|
||||
}
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
// Identical to LazyUsize except with bool instead of usize.
|
||||
pub struct LazyBool(LazyUsize);
|
||||
|
||||
impl LazyBool {
|
||||
pub const fn new() -> Self {
|
||||
Self(LazyUsize::new())
|
||||
}
|
||||
|
||||
pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {
|
||||
self.0.unsync_init(|| init() as usize) != 0
|
||||
}
|
||||
}
|
||||
use core::{mem::MaybeUninit, ptr};
|
||||
|
||||
/// Polyfill for `maybe_uninit_slice` feature's
|
||||
/// `MaybeUninit::slice_assume_init_mut`. Every element of `slice` must have
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
// Copyright 2019 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![allow(dead_code)]
|
||||
use crate::Error;
|
||||
use core::{
|
||||
cmp::min,
|
||||
mem::MaybeUninit,
|
||||
num::NonZeroU32,
|
||||
ptr::NonNull,
|
||||
|
@ -70,17 +62,19 @@ pub fn sys_fill_exact(
|
|||
) -> Result<(), Error> {
|
||||
while !buf.is_empty() {
|
||||
let res = sys_fill(buf);
|
||||
if res < 0 {
|
||||
let err = last_os_error();
|
||||
// We should try again if the call was interrupted.
|
||||
if err.raw_os_error() != Some(libc::EINTR) {
|
||||
return Err(err);
|
||||
match res {
|
||||
res if res > 0 => buf = buf.get_mut(res as usize..).ok_or(Error::UNEXPECTED)?,
|
||||
-1 => {
|
||||
let err = last_os_error();
|
||||
// We should try again if the call was interrupted.
|
||||
if err.raw_os_error() != Some(libc::EINTR) {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We don't check for EOF (ret = 0) as the data we are reading
|
||||
// Negative return codes not equal to -1 should be impossible.
|
||||
// EOF (ret = 0) should be impossible, as the data we are reading
|
||||
// should be an infinite stream of random bytes.
|
||||
let len = min(res as usize, buf.len());
|
||||
buf = &mut buf[len..];
|
||||
_ => return Err(Error::UNEXPECTED),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -157,3 +151,16 @@ pub unsafe fn open_readonly(path: &str) -> Result<libc::c_int, Error> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Thin wrapper around the `getrandom()` Linux system call
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub fn getrandom_syscall(buf: &mut [MaybeUninit<u8>]) -> libc::ssize_t {
|
||||
unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_getrandom,
|
||||
buf.as_mut_ptr() as *mut libc::c_void,
|
||||
buf.len(),
|
||||
0,
|
||||
) as libc::ssize_t
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2021 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for PS Vita
|
||||
use crate::{util_libc::last_os_error, Error};
|
||||
use core::mem::MaybeUninit;
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for VxWorks
|
||||
use crate::{util_libc::last_os_error, Error};
|
||||
use core::{
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for WASI
|
||||
use crate::Error;
|
||||
use core::{
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for Windows
|
||||
use crate::Error;
|
||||
use core::{ffi::c_void, mem::MaybeUninit, num::NonZeroU32, ptr};
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
use getrandom::Error;
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
#[path = "../src/lazy.rs"]
|
||||
mod lazy;
|
||||
#[path = "../src/rdrand.rs"]
|
||||
mod rdrand;
|
||||
#[path = "../src/util.rs"]
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -11,9 +11,9 @@
|
|||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.64"
|
||||
rust-version = "1.71"
|
||||
name = "prio"
|
||||
version = "0.15.3"
|
||||
version = "0.16.2"
|
||||
authors = [
|
||||
"Josh Aas <jaas@kflag.net>",
|
||||
"Tim Geoghegan <timg@letsencrypt.org>",
|
||||
|
@ -54,7 +54,7 @@ name = "cycle_counts"
|
|||
harness = false
|
||||
|
||||
[dependencies.aes]
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
optional = true
|
||||
|
||||
[dependencies.bitvec]
|
||||
|
@ -62,24 +62,29 @@ version = "1.0.1"
|
|||
optional = true
|
||||
|
||||
[dependencies.byteorder]
|
||||
version = "1.4.3"
|
||||
version = "1.5.0"
|
||||
|
||||
[dependencies.ctr]
|
||||
version = "0.9.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.fiat-crypto]
|
||||
version = "0.2.1"
|
||||
version = "0.2.6"
|
||||
optional = true
|
||||
|
||||
[dependencies.fixed]
|
||||
version = "1.23"
|
||||
version = "1.26"
|
||||
optional = true
|
||||
|
||||
[dependencies.getrandom]
|
||||
version = "0.2.10"
|
||||
version = "0.2.12"
|
||||
features = ["std"]
|
||||
|
||||
[dependencies.hex]
|
||||
version = "0.4.3"
|
||||
features = ["serde"]
|
||||
optional = true
|
||||
|
||||
[dependencies.hmac]
|
||||
version = "0.12.1"
|
||||
optional = true
|
||||
|
@ -93,11 +98,11 @@ features = [
|
|||
optional = true
|
||||
|
||||
[dependencies.num-integer]
|
||||
version = "0.1.45"
|
||||
version = "0.1.46"
|
||||
optional = true
|
||||
|
||||
[dependencies.num-iter]
|
||||
version = "0.1.43"
|
||||
version = "0.1.44"
|
||||
optional = true
|
||||
|
||||
[dependencies.num-rational]
|
||||
|
@ -106,7 +111,7 @@ features = ["serde"]
|
|||
optional = true
|
||||
|
||||
[dependencies.num-traits]
|
||||
version = "0.2.16"
|
||||
version = "0.2.18"
|
||||
optional = true
|
||||
|
||||
[dependencies.rand]
|
||||
|
@ -117,15 +122,19 @@ optional = true
|
|||
version = "0.6.4"
|
||||
|
||||
[dependencies.rayon]
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.sha2]
|
||||
version = "0.10.7"
|
||||
version = "0.10.8"
|
||||
optional = true
|
||||
|
||||
[dependencies.sha3]
|
||||
|
@ -137,11 +146,15 @@ version = "2.5.0"
|
|||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.zipf]
|
||||
version = "7.0.1"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies.assert_matches]
|
||||
version = "1.5.0"
|
||||
|
||||
[dev-dependencies.base64]
|
||||
version = "0.21.4"
|
||||
version = "0.22.0"
|
||||
|
||||
[dev-dependencies.cfg-if]
|
||||
version = "1.0.0"
|
||||
|
@ -152,19 +165,12 @@ version = "0.5"
|
|||
[dev-dependencies.fixed-macro]
|
||||
version = "1.2.0"
|
||||
|
||||
[dev-dependencies.hex]
|
||||
version = "0.4.3"
|
||||
features = ["serde"]
|
||||
|
||||
[dev-dependencies.hex-literal]
|
||||
version = "0.4.1"
|
||||
|
||||
[dev-dependencies.iai]
|
||||
version = "0.1"
|
||||
|
||||
[dev-dependencies.itertools]
|
||||
version = "0.11.0"
|
||||
|
||||
[dev-dependencies.modinverse]
|
||||
version = "0.1.0"
|
||||
|
||||
|
@ -172,24 +178,20 @@ version = "0.1.0"
|
|||
version = "0.4.4"
|
||||
|
||||
[dev-dependencies.once_cell]
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.8"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.statrs]
|
||||
version = "0.16.0"
|
||||
|
||||
[dev-dependencies.zipf]
|
||||
version = "7.0.1"
|
||||
|
||||
[features]
|
||||
crypto-dependencies = [
|
||||
"aes",
|
||||
"ctr",
|
||||
"hmac",
|
||||
"sha2",
|
||||
]
|
||||
default = ["crypto-dependencies"]
|
||||
experimental = [
|
||||
|
@ -204,9 +206,9 @@ experimental = [
|
|||
"rand",
|
||||
]
|
||||
multithreaded = ["rayon"]
|
||||
prio2 = [
|
||||
"crypto-dependencies",
|
||||
"hmac",
|
||||
"sha2",
|
||||
test-util = [
|
||||
"hex",
|
||||
"rand",
|
||||
"serde_json",
|
||||
"zipf",
|
||||
]
|
||||
test-util = ["rand"]
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# libprio-rs
|
||||
[![Build Status]][actions] [![Latest Version]][crates.io] [![Docs badge]][docs.rs]
|
||||
[![Latest Version]][crates.io] [![Docs badge]][docs.rs]
|
||||
|
||||
[Build Status]: https://github.com/divviup/libprio-rs/workflows/ci-build/badge.svg
|
||||
[actions]: https://github.com/divviup/libprio-rs/actions?query=branch%3Amain
|
||||
[Latest Version]: https://img.shields.io/crates/v/prio.svg
|
||||
[crates.io]: https://crates.io/crates/prio
|
||||
[Docs badge]: https://img.shields.io/badge/docs.rs-rustdoc-green
|
||||
|
@ -38,12 +36,13 @@ increases (e.g., 0.10 to 0.11).
|
|||
| ----- | ---------- | ------------- | ------------- | --------------------- | ------ |
|
||||
| 0.8 | `release/0.8` | [`draft-irtf-cfrg-vdaf-01`][vdaf-01] | [`draft-ietf-ppm-dap-01`][dap-01] | Yes | Unmaintained as of March 28, 2023 |
|
||||
| 0.9 | `release/0.9` | [`draft-irtf-cfrg-vdaf-03`][vdaf-03] | [`draft-ietf-ppm-dap-02`][dap-02] and [`draft-ietf-ppm-dap-03`][dap-03] | Yes | Unmaintained as of September 22, 2022 |
|
||||
| 0.10 | `release/0.10` | [`draft-irtf-cfrg-vdaf-03`][vdaf-03] | [`draft-ietf-ppm-dap-02`][dap-02] and [`draft-ietf-ppm-dap-03`][dap-03] | Yes | Supported |
|
||||
| 0.10 | `release/0.10` | [`draft-irtf-cfrg-vdaf-03`][vdaf-03] | [`draft-ietf-ppm-dap-02`][dap-02] and [`draft-ietf-ppm-dap-03`][dap-03] | Yes | Unmaintained as of November 14, 2023 |
|
||||
| 0.11 | `release/0.11` | [`draft-irtf-cfrg-vdaf-04`][vdaf-04] | N/A | Yes | Unmaintained |
|
||||
| 0.12 | `release/0.12` | [`draft-irtf-cfrg-vdaf-05`][vdaf-05] | [`draft-ietf-ppm-dap-04`][dap-04] | Yes | Supported |
|
||||
| 0.13 | `release/0.13` | [`draft-irtf-cfrg-vdaf-06`][vdaf-06] | [`draft-ietf-ppm-dap-05`][dap-05] | Yes | Unmaintained |
|
||||
| 0.14 | `release/0.14` | [`draft-irtf-cfrg-vdaf-06`][vdaf-06] | [`draft-ietf-ppm-dap-05`][dap-05] | Yes | Unmaintained |
|
||||
| 0.15 | `main` | [`draft-irtf-cfrg-vdaf-07`][vdaf-07] | [`draft-ietf-ppm-dap-06`][dap-06] | Yes | Supported |
|
||||
| 0.15 | `release/0.15` | [`draft-irtf-cfrg-vdaf-07`][vdaf-07] | [`draft-ietf-ppm-dap-07`][dap-07] | Yes | Supported |
|
||||
| 0.16 | `main` | [`draft-irtf-cfrg-vdaf-08`][vdaf-08] | [`draft-ietf-ppm-dap-09`][dap-09] | Yes | Supported |
|
||||
|
||||
[vdaf-01]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/01/
|
||||
[vdaf-03]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/03/
|
||||
|
@ -51,12 +50,14 @@ increases (e.g., 0.10 to 0.11).
|
|||
[vdaf-05]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/05/
|
||||
[vdaf-06]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/06/
|
||||
[vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
[vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
[dap-01]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/01/
|
||||
[dap-02]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/02/
|
||||
[dap-03]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/03/
|
||||
[dap-04]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/04/
|
||||
[dap-05]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/05/
|
||||
[dap-06]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/06/
|
||||
[dap-07]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/07/
|
||||
[dap-09]: https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/09/
|
||||
[enpa]: https://www.abetterinternet.org/post/prio-services-for-covid-en/
|
||||
[enpa-whitepaper]: https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf
|
||||
[prio-server]: https://github.com/divviup/prio-server
|
||||
|
@ -68,9 +69,11 @@ increases (e.g., 0.10 to 0.11).
|
|||
|
||||
This crate defines the following feature flags:
|
||||
|
||||
|Name|Default feature?|Description|
|
||||
|---|---|---|
|
||||
|`crypto-dependencies`|Yes|Enables dependencies on various RustCrypto crates, and uses them to implement `XofShake128` to support VDAFs.|
|
||||
|`experimental`|No|Certain experimental APIs are guarded by this feature. They may undergo breaking changes in future patch releases, as an exception to semantic versioning.|
|
||||
|`multithreaded`|No|Enables certain Prio3 VDAF implementations that use `rayon` for parallelization of gadget evaluations.|
|
||||
|`prio2`|No|Enables the Prio v2 API, and a VDAF based on the Prio2 system.|
|
||||
|Name|Default feature?|Description|Semver stable?|
|
||||
|---|---|---|---|
|
||||
|`crypto-dependencies`|Yes|Enables dependencies on various RustCrypto crates, and uses them to implement `XofTurboShake128` to support VDAFs.|✅|
|
||||
|`experimental`|No|Certain experimental APIs are guarded by this feature.|❌|
|
||||
|`multithreaded`|No|Enables certain Prio3 VDAF implementations that use `rayon` for parallelization of gadget evaluations.|✅|
|
||||
|`test-util`|No|Enables test utilities for VDAF users and VDAF implementers.|❌|
|
||||
|
||||
Features that are not marked as "Semver stable" may undergo breaking changes in future patch releases, as an exception to semantic versioning.
|
||||
|
|
|
@ -5,15 +5,12 @@ use iai::black_box;
|
|||
#[cfg(feature = "experimental")]
|
||||
use prio::{
|
||||
codec::{Decode, Encode, ParameterizedDecode},
|
||||
field::{Field255, FieldElement},
|
||||
field::{Field255, FieldElement, FieldPrio2},
|
||||
idpf::{Idpf, IdpfInput, IdpfPublicShare, RingBufferCache},
|
||||
vdaf::{poplar1::Poplar1IdpfValue, xof::Seed},
|
||||
};
|
||||
#[cfg(feature = "prio2")]
|
||||
use prio::{
|
||||
field::FieldPrio2,
|
||||
vdaf::{
|
||||
poplar1::Poplar1IdpfValue,
|
||||
prio2::{Prio2, Prio2PrepareShare},
|
||||
xof::Seed,
|
||||
Aggregator, Share,
|
||||
},
|
||||
};
|
||||
|
@ -45,7 +42,7 @@ fn prng_4096() -> Vec<Field128> {
|
|||
prng(4096)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_client(size: usize) -> Vec<Share<FieldPrio2, 32>> {
|
||||
let prio2 = Prio2::new(size).unwrap();
|
||||
let input = vec![0u32; size];
|
||||
|
@ -53,22 +50,22 @@ fn prio2_client(size: usize) -> Vec<Share<FieldPrio2, 32>> {
|
|||
prio2.shard(&black_box(input), &black_box(nonce)).unwrap().1
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_client_10() -> Vec<Share<FieldPrio2, 32>> {
|
||||
prio2_client(10)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_client_100() -> Vec<Share<FieldPrio2, 32>> {
|
||||
prio2_client(100)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_client_1000() -> Vec<Share<FieldPrio2, 32>> {
|
||||
prio2_client(1000)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_shard_and_prepare(size: usize) -> Prio2PrepareShare {
|
||||
let prio2 = Prio2::new(size).unwrap();
|
||||
let input = vec![0u32; size];
|
||||
|
@ -80,24 +77,24 @@ fn prio2_shard_and_prepare(size: usize) -> Prio2PrepareShare {
|
|||
.1
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_shard_and_prepare_10() -> Prio2PrepareShare {
|
||||
prio2_shard_and_prepare(10)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_shard_and_prepare_100() -> Prio2PrepareShare {
|
||||
prio2_shard_and_prepare(100)
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2_shard_and_prepare_1000() -> Prio2PrepareShare {
|
||||
prio2_shard_and_prepare(1000)
|
||||
}
|
||||
|
||||
fn prio3_client_count() -> Vec<Prio3InputShare<Field64, 16>> {
|
||||
let prio3 = Prio3::new_count(2).unwrap();
|
||||
let measurement = 1;
|
||||
let measurement = true;
|
||||
let nonce = [0; 16];
|
||||
prio3
|
||||
.shard(&black_box(measurement), &black_box(nonce))
|
||||
|
@ -241,7 +238,7 @@ fn idpf_codec() {
|
|||
.unwrap();
|
||||
let bits = 4;
|
||||
let public_share = IdpfPublicShare::<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>::get_decoded_with_param(&bits, &data).unwrap();
|
||||
let encoded = public_share.get_encoded();
|
||||
let encoded = public_share.get_encoded().unwrap();
|
||||
let _ = black_box(encoded.len());
|
||||
}
|
||||
|
||||
|
@ -261,34 +258,10 @@ macro_rules! main_base {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
macro_rules! main_add_prio2 {
|
||||
( $( $func_name:ident ),* $(,)* ) => {
|
||||
main_base!(
|
||||
prio2_client_10,
|
||||
prio2_client_100,
|
||||
prio2_client_1000,
|
||||
prio2_shard_and_prepare_10,
|
||||
prio2_shard_and_prepare_100,
|
||||
prio2_shard_and_prepare_1000,
|
||||
$( $func_name, )*
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "prio2"))]
|
||||
macro_rules! main_add_prio2 {
|
||||
( $( $func_name:ident ),* $(,)* ) => {
|
||||
main_base!(
|
||||
$( $func_name, )*
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "multithreaded")]
|
||||
macro_rules! main_add_multithreaded {
|
||||
( $( $func_name:ident ),* $(,)* ) => {
|
||||
main_add_prio2!(
|
||||
main_base!(
|
||||
prio3_client_count_vec_multithreaded_1000,
|
||||
$( $func_name, )*
|
||||
);
|
||||
|
@ -298,7 +271,7 @@ macro_rules! main_add_multithreaded {
|
|||
#[cfg(not(feature = "multithreaded"))]
|
||||
macro_rules! main_add_multithreaded {
|
||||
( $( $func_name:ident ),* $(,)* ) => {
|
||||
main_add_prio2!(
|
||||
main_base!(
|
||||
$( $func_name, )*
|
||||
);
|
||||
};
|
||||
|
@ -308,6 +281,12 @@ macro_rules! main_add_multithreaded {
|
|||
macro_rules! main_add_experimental {
|
||||
( $( $func_name:ident ),* $(,)* ) => {
|
||||
main_add_multithreaded!(
|
||||
prio2_client_10,
|
||||
prio2_client_100,
|
||||
prio2_client_1000,
|
||||
prio2_shard_and_prepare_10,
|
||||
prio2_shard_and_prepare_100,
|
||||
prio2_shard_and_prepare_1000,
|
||||
idpf_codec,
|
||||
idpf_poplar_gen_8,
|
||||
idpf_poplar_gen_128,
|
||||
|
|
|
@ -15,7 +15,9 @@ use num_rational::Ratio;
|
|||
use num_traits::ToPrimitive;
|
||||
#[cfg(feature = "experimental")]
|
||||
use prio::dp::distributions::DiscreteGaussian;
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
use prio::idpf::test_utils::generate_zipf_distributed_batch;
|
||||
#[cfg(feature = "experimental")]
|
||||
use prio::vdaf::prio2::Prio2;
|
||||
use prio::{
|
||||
benchmarked::*,
|
||||
|
@ -35,8 +37,6 @@ use rand::prelude::*;
|
|||
#[cfg(feature = "experimental")]
|
||||
use std::iter;
|
||||
use std::time::Duration;
|
||||
#[cfg(feature = "experimental")]
|
||||
use zipf::ZipfDistribution;
|
||||
|
||||
/// Seed for generation of random benchmark inputs.
|
||||
///
|
||||
|
@ -116,7 +116,7 @@ fn poly_mul(c: &mut Criterion) {
|
|||
}
|
||||
|
||||
/// Benchmark prio2.
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn prio2(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("prio2_shard");
|
||||
for input_length in [10, 100, 1_000] {
|
||||
|
@ -164,14 +164,14 @@ fn prio3(c: &mut Criterion) {
|
|||
|
||||
c.bench_function("prio3count_shard", |b| {
|
||||
let vdaf = Prio3::new_count(num_shares).unwrap();
|
||||
let measurement = black_box(1);
|
||||
let measurement = black_box(true);
|
||||
let nonce = black_box([0u8; 16]);
|
||||
b.iter(|| vdaf.shard(&measurement, &nonce).unwrap());
|
||||
});
|
||||
|
||||
c.bench_function("prio3count_prepare_init", |b| {
|
||||
let vdaf = Prio3::new_count(num_shares).unwrap();
|
||||
let measurement = black_box(1);
|
||||
let measurement = black_box(true);
|
||||
let nonce = black_box([0u8; 16]);
|
||||
let verify_key = black_box([0u8; 16]);
|
||||
let (public_share, input_shares) = vdaf.shard(&measurement, &nonce).unwrap();
|
||||
|
@ -712,7 +712,7 @@ fn poplar1(c: &mut Criterion) {
|
|||
for size in test_sizes.iter() {
|
||||
group.throughput(Throughput::Bytes(*size as u64 / 8));
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
|
||||
let vdaf = Poplar1::new_shake128(size);
|
||||
let vdaf = Poplar1::new_turboshake128(size);
|
||||
let mut rng = StdRng::seed_from_u64(RNG_SEED);
|
||||
let nonce = rng.gen::<[u8; 16]>();
|
||||
|
||||
|
@ -736,7 +736,7 @@ fn poplar1(c: &mut Criterion) {
|
|||
for size in test_sizes.iter() {
|
||||
group.measurement_time(Duration::from_secs(30)); // slower benchmark
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
|
||||
let vdaf = Poplar1::new_shake128(size);
|
||||
let vdaf = Poplar1::new_turboshake128(size);
|
||||
let mut rng = StdRng::seed_from_u64(RNG_SEED);
|
||||
|
||||
b.iter_batched(
|
||||
|
@ -746,7 +746,7 @@ fn poplar1(c: &mut Criterion) {
|
|||
|
||||
// Parameters are chosen to match Chris Wood's experimental setup:
|
||||
// https://github.com/chris-wood/heavy-hitter-comparison
|
||||
let (measurements, prefix_tree) = poplar1_generate_zipf_distributed_batch(
|
||||
let (measurements, prefix_tree) = generate_zipf_distributed_batch(
|
||||
&mut rng, // rng
|
||||
size, // bits
|
||||
10, // threshold
|
||||
|
@ -794,83 +794,54 @@ fn poplar1(c: &mut Criterion) {
|
|||
group.finish();
|
||||
}
|
||||
|
||||
/// Generate a set of Poplar1 measurements with the given bit length `bits`. They are sampled
|
||||
/// according to the Zipf distribution with parameters `zipf_support` and `zipf_exponent`. Return
|
||||
/// the measurements, along with the prefix tree for the desired threshold.
|
||||
///
|
||||
/// The prefix tree consists of a sequence of candidate prefixes for each level. For a given level,
|
||||
/// the candidate prefixes are computed from the hit counts of the prefixes at the previous level:
|
||||
/// For any prefix `p` whose hit count is at least the desired threshold, add `p || 0` and `p || 1`
|
||||
/// to the list.
|
||||
/// Benchmark VIDPF performance.
|
||||
#[cfg(feature = "experimental")]
|
||||
fn poplar1_generate_zipf_distributed_batch(
|
||||
rng: &mut impl Rng,
|
||||
bits: usize,
|
||||
threshold: usize,
|
||||
measurement_count: usize,
|
||||
zipf_support: usize,
|
||||
zipf_exponent: f64,
|
||||
) -> (Vec<IdpfInput>, Vec<Vec<IdpfInput>>) {
|
||||
// Generate random inputs.
|
||||
let mut inputs = Vec::with_capacity(zipf_support);
|
||||
for _ in 0..zipf_support {
|
||||
let bools: Vec<bool> = (0..bits).map(|_| rng.gen()).collect();
|
||||
inputs.push(IdpfInput::from_bools(&bools));
|
||||
fn vidpf(c: &mut Criterion) {
|
||||
use prio::vidpf::{Vidpf, VidpfInput, VidpfWeight};
|
||||
|
||||
let test_sizes = [8usize, 8 * 16, 8 * 256];
|
||||
const NONCE_SIZE: usize = 16;
|
||||
const NONCE: &[u8; NONCE_SIZE] = b"Test Nonce VIDPF";
|
||||
|
||||
let mut group = c.benchmark_group("vidpf_gen");
|
||||
for size in test_sizes.iter() {
|
||||
group.throughput(Throughput::Bytes(*size as u64 / 8));
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
|
||||
let bits = iter::repeat_with(random).take(size).collect::<Vec<bool>>();
|
||||
let input = VidpfInput::from_bools(&bits);
|
||||
let weight = VidpfWeight::from(vec![Field255::one(), Field255::one()]);
|
||||
|
||||
let vidpf = Vidpf::<VidpfWeight<Field255>, NONCE_SIZE>::new(2);
|
||||
|
||||
b.iter(|| {
|
||||
let _ = vidpf.gen(&input, &weight, NONCE).unwrap();
|
||||
});
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
|
||||
// Sample a number of inputs according to the Zipf distribution.
|
||||
let mut samples = Vec::with_capacity(measurement_count);
|
||||
let zipf = ZipfDistribution::new(zipf_support, zipf_exponent).unwrap();
|
||||
for _ in 0..measurement_count {
|
||||
samples.push(inputs[zipf.sample(rng) - 1].clone());
|
||||
let mut group = c.benchmark_group("vidpf_eval");
|
||||
for size in test_sizes.iter() {
|
||||
group.throughput(Throughput::Bytes(*size as u64 / 8));
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| {
|
||||
let bits = iter::repeat_with(random).take(size).collect::<Vec<bool>>();
|
||||
let input = VidpfInput::from_bools(&bits);
|
||||
let weight = VidpfWeight::from(vec![Field255::one(), Field255::one()]);
|
||||
let vidpf = Vidpf::<VidpfWeight<Field255>, NONCE_SIZE>::new(2);
|
||||
|
||||
let (public, keys) = vidpf.gen(&input, &weight, NONCE).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
let _ = vidpf.eval(&keys[0], &public, &input, NONCE).unwrap();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Compute the prefix tree for the desired threshold.
|
||||
let mut prefix_tree = Vec::with_capacity(bits);
|
||||
prefix_tree.push(vec![
|
||||
IdpfInput::from_bools(&[false]),
|
||||
IdpfInput::from_bools(&[true]),
|
||||
]);
|
||||
|
||||
for level in 0..bits - 1 {
|
||||
// Compute the hit count of each prefix from the previous level.
|
||||
let mut hit_counts = vec![0; prefix_tree[level].len()];
|
||||
for (hit_count, prefix) in hit_counts.iter_mut().zip(prefix_tree[level].iter()) {
|
||||
for sample in samples.iter() {
|
||||
let mut is_prefix = true;
|
||||
for j in 0..prefix.len() {
|
||||
if prefix[j] != sample[j] {
|
||||
is_prefix = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if is_prefix {
|
||||
*hit_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the next set of candidate prefixes.
|
||||
let mut next_prefixes = Vec::new();
|
||||
for (hit_count, prefix) in hit_counts.iter().zip(prefix_tree[level].iter()) {
|
||||
if *hit_count >= threshold {
|
||||
next_prefixes.push(prefix.clone_with_suffix(&[false]));
|
||||
next_prefixes.push(prefix.clone_with_suffix(&[true]));
|
||||
}
|
||||
}
|
||||
prefix_tree.push(next_prefixes);
|
||||
}
|
||||
|
||||
(samples, prefix_tree)
|
||||
group.finish();
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "prio2", feature = "experimental"))]
|
||||
criterion_group!(benches, poplar1, prio3, prio2, poly_mul, prng, idpf, dp_noise);
|
||||
#[cfg(all(not(feature = "prio2"), feature = "experimental"))]
|
||||
criterion_group!(benches, poplar1, prio3, poly_mul, prng, idpf, dp_noise);
|
||||
#[cfg(all(feature = "prio2", not(feature = "experimental")))]
|
||||
criterion_group!(benches, prio3, prio2, prng, poly_mul);
|
||||
#[cfg(all(not(feature = "prio2"), not(feature = "experimental")))]
|
||||
#[cfg(feature = "experimental")]
|
||||
criterion_group!(benches, poplar1, prio3, prio2, poly_mul, prng, idpf, dp_noise, vidpf);
|
||||
#[cfg(not(feature = "experimental"))]
|
||||
criterion_group!(benches, prio3, prng, poly_mul);
|
||||
|
||||
criterion_main!(benches);
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env sage
|
||||
|
||||
# This file recomputes the values in src/fp.rs for each FFT-friendly finite
|
||||
# field.
|
||||
|
||||
import pprint
|
||||
|
||||
|
||||
class Field:
|
||||
# The name of the field.
|
||||
name: str
|
||||
|
||||
# The prime modulus that defines the field.
|
||||
modulus: Integer
|
||||
|
||||
# A generator element that generates a large subgroup with an order that's
|
||||
# a power of two. This is _not_ in Montgomery representation.
|
||||
generator_element: Integer
|
||||
|
||||
# The base 2 logarithm of the order of the FFT-friendly multiplicative
|
||||
# subgroup. The generator element will be a 2^num_roots-th root of unity.
|
||||
num_roots: Integer
|
||||
|
||||
def __init__(self, name, modulus, generator_element):
|
||||
assert is_prime(modulus)
|
||||
self.name = name
|
||||
self.modulus = modulus
|
||||
self.generator_element = generator_element
|
||||
|
||||
self.num_roots = None
|
||||
for (prime, power) in factor(modulus - 1):
|
||||
if prime == 2:
|
||||
self.num_roots = power
|
||||
break
|
||||
else:
|
||||
raise Exception(
|
||||
"Multiplicative subgroup order is not a multiple of two"
|
||||
)
|
||||
|
||||
def mu(self):
|
||||
"""
|
||||
Computes mu, a constant used during multiplication. It is defined by
|
||||
mu = (-p)^-1 mod r, where r is the modulus implicitly used in wrapping
|
||||
machine word operations.
|
||||
"""
|
||||
r = 2 ^ 64
|
||||
return (-self.modulus).inverse_mod(r)
|
||||
|
||||
def r2(self):
|
||||
"""
|
||||
Computes R^2 mod p. This constant is used when converting into
|
||||
Montgomery representation. R is the machine word-friendly modulus
|
||||
used in the Montgomery representation.
|
||||
"""
|
||||
R = 2 ^ 128
|
||||
return R ^ 2 % self.modulus
|
||||
|
||||
def to_montgomery(self, element):
|
||||
"""
|
||||
Transforms an element into its Montgomery representation.
|
||||
"""
|
||||
R = 2 ^ 128
|
||||
return element * R % self.modulus
|
||||
|
||||
def bit_mask(self):
|
||||
"""
|
||||
An integer with the same bit length as the prime modulus, but with all
|
||||
bits set.
|
||||
"""
|
||||
return 2 ^ (self.modulus.nbits()) - 1
|
||||
|
||||
def roots(self):
|
||||
"""
|
||||
Returns a list of roots of unity, in Montgomery representation. The
|
||||
value at index i is a 2^i-th root of unity. Note that the first array
|
||||
element will thus be the Montgomery representation of one.
|
||||
"""
|
||||
return [
|
||||
self.to_montgomery(
|
||||
pow(
|
||||
self.generator_element,
|
||||
2 ^ (self.num_roots - i),
|
||||
self.modulus,
|
||||
)
|
||||
)
|
||||
for i in range(min(self.num_roots, 20) + 1)
|
||||
]
|
||||
|
||||
|
||||
FIELDS = [
|
||||
Field(
|
||||
"FieldPrio2",
|
||||
2 ^ 20 * 4095 + 1,
|
||||
3925978153,
|
||||
),
|
||||
Field(
|
||||
"Field64",
|
||||
2 ^ 32 * 4294967295 + 1,
|
||||
pow(7, 4294967295, 2 ^ 32 * 4294967295 + 1),
|
||||
),
|
||||
Field(
|
||||
"Field128",
|
||||
2 ^ 66 * 4611686018427387897 + 1,
|
||||
pow(7, 4611686018427387897, 2 ^ 66 * 4611686018427387897 + 1),
|
||||
),
|
||||
]
|
||||
for field in FIELDS:
|
||||
print(field.name)
|
||||
print(f"p: {field.modulus}")
|
||||
print(f"mu: {field.mu()}")
|
||||
print(f"r2: {field.r2()}")
|
||||
print(f"g: {field.to_montgomery(field.generator_element)}")
|
||||
print(f"num_roots: {field.num_roots}")
|
||||
print(f"bit_mask: {field.bit_mask()}")
|
||||
print("roots:")
|
||||
pprint.pprint(field.roots())
|
||||
print()
|
|
@ -20,6 +20,7 @@ use std::{
|
|||
|
||||
/// An error that occurred during decoding.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CodecError {
|
||||
/// An I/O error.
|
||||
#[error("I/O error")]
|
||||
|
@ -33,6 +34,10 @@ pub enum CodecError {
|
|||
#[error("length prefix of encoded vector overflows buffer: {0}")]
|
||||
LengthPrefixTooBig(usize),
|
||||
|
||||
/// The byte length of a vector exceeded the range of its length prefix.
|
||||
#[error("vector length exceeded range of length prefix")]
|
||||
LengthPrefixOverflow,
|
||||
|
||||
/// Custom errors from [`Decode`] implementations.
|
||||
#[error("other error: {0}")]
|
||||
Other(#[source] Box<dyn Error + 'static + Send + Sync>),
|
||||
|
@ -97,10 +102,10 @@ impl<D: Decode + ?Sized, T> ParameterizedDecode<T> for D {
|
|||
/// Describes how to encode objects into a byte sequence.
|
||||
pub trait Encode {
|
||||
/// Append the encoded form of this object to the end of `bytes`, growing the vector as needed.
|
||||
fn encode(&self, bytes: &mut Vec<u8>);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError>;
|
||||
|
||||
/// Convenience method to encode a value into a new `Vec<u8>`.
|
||||
fn get_encoded(&self) -> Vec<u8> {
|
||||
fn get_encoded(&self) -> Result<Vec<u8>, CodecError> {
|
||||
self.get_encoded_with_param(&())
|
||||
}
|
||||
|
||||
|
@ -116,17 +121,21 @@ pub trait ParameterizedEncode<P> {
|
|||
/// Append the encoded form of this object to the end of `bytes`, growing the vector as needed.
|
||||
/// `encoding_parameter` provides details of the wire encoding, used to control how the value
|
||||
/// is encoded.
|
||||
fn encode_with_param(&self, encoding_parameter: &P, bytes: &mut Vec<u8>);
|
||||
fn encode_with_param(
|
||||
&self,
|
||||
encoding_parameter: &P,
|
||||
bytes: &mut Vec<u8>,
|
||||
) -> Result<(), CodecError>;
|
||||
|
||||
/// Convenience method to encode a value into a new `Vec<u8>`.
|
||||
fn get_encoded_with_param(&self, encoding_parameter: &P) -> Vec<u8> {
|
||||
fn get_encoded_with_param(&self, encoding_parameter: &P) -> Result<Vec<u8>, CodecError> {
|
||||
let mut ret = if let Some(length) = self.encoded_len_with_param(encoding_parameter) {
|
||||
Vec::with_capacity(length)
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
self.encode_with_param(encoding_parameter, &mut ret);
|
||||
ret
|
||||
self.encode_with_param(encoding_parameter, &mut ret)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Returns an optional hint indicating how many bytes will be required to encode this value, or
|
||||
|
@ -139,7 +148,11 @@ pub trait ParameterizedEncode<P> {
|
|||
/// Provide a blanket implementation so that any [`Encode`] can be used as a
|
||||
/// `ParameterizedEncode<T>` for any `T`.
|
||||
impl<E: Encode + ?Sized, T> ParameterizedEncode<T> for E {
|
||||
fn encode_with_param(&self, _encoding_parameter: &T, bytes: &mut Vec<u8>) {
|
||||
fn encode_with_param(
|
||||
&self,
|
||||
_encoding_parameter: &T,
|
||||
bytes: &mut Vec<u8>,
|
||||
) -> Result<(), CodecError> {
|
||||
self.encode(bytes)
|
||||
}
|
||||
|
||||
|
@ -155,7 +168,9 @@ impl Decode for () {
|
|||
}
|
||||
|
||||
impl Encode for () {
|
||||
fn encode(&self, _bytes: &mut Vec<u8>) {}
|
||||
fn encode(&self, _bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
Some(0)
|
||||
|
@ -171,8 +186,9 @@ impl Decode for u8 {
|
|||
}
|
||||
|
||||
impl Encode for u8 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.push(*self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -187,8 +203,9 @@ impl Decode for u16 {
|
|||
}
|
||||
|
||||
impl Encode for u16 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.extend_from_slice(&u16::to_be_bytes(*self));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -208,9 +225,10 @@ impl Decode for U24 {
|
|||
}
|
||||
|
||||
impl Encode for U24 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
// Encode lower three bytes of the u32 as u24
|
||||
bytes.extend_from_slice(&u32::to_be_bytes(self.0)[1..]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -225,8 +243,9 @@ impl Decode for u32 {
|
|||
}
|
||||
|
||||
impl Encode for u32 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.extend_from_slice(&u32::to_be_bytes(*self));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -241,8 +260,9 @@ impl Decode for u64 {
|
|||
}
|
||||
|
||||
impl Encode for u64 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.extend_from_slice(&u64::to_be_bytes(*self));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -257,18 +277,19 @@ pub fn encode_u8_items<P, E: ParameterizedEncode<P>>(
|
|||
bytes: &mut Vec<u8>,
|
||||
encoding_parameter: &P,
|
||||
items: &[E],
|
||||
) {
|
||||
) -> Result<(), CodecError> {
|
||||
// Reserve space to later write length
|
||||
let len_offset = bytes.len();
|
||||
bytes.push(0);
|
||||
|
||||
for item in items {
|
||||
item.encode_with_param(encoding_parameter, bytes);
|
||||
item.encode_with_param(encoding_parameter, bytes)?;
|
||||
}
|
||||
|
||||
let len = bytes.len() - len_offset - 1;
|
||||
assert!(len <= usize::from(u8::MAX));
|
||||
bytes[len_offset] = len as u8;
|
||||
let len =
|
||||
u8::try_from(bytes.len() - len_offset - 1).map_err(|_| CodecError::LengthPrefixOverflow)?;
|
||||
bytes[len_offset] = len;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Decode `bytes` into a vector of `D` values, treating `bytes` as a [variable-length vector][1] of
|
||||
|
@ -292,20 +313,19 @@ pub fn encode_u16_items<P, E: ParameterizedEncode<P>>(
|
|||
bytes: &mut Vec<u8>,
|
||||
encoding_parameter: &P,
|
||||
items: &[E],
|
||||
) {
|
||||
) -> Result<(), CodecError> {
|
||||
// Reserve space to later write length
|
||||
let len_offset = bytes.len();
|
||||
0u16.encode(bytes);
|
||||
0u16.encode(bytes)?;
|
||||
|
||||
for item in items {
|
||||
item.encode_with_param(encoding_parameter, bytes);
|
||||
item.encode_with_param(encoding_parameter, bytes)?;
|
||||
}
|
||||
|
||||
let len = bytes.len() - len_offset - 2;
|
||||
assert!(len <= usize::from(u16::MAX));
|
||||
for (offset, byte) in u16::to_be_bytes(len as u16).iter().enumerate() {
|
||||
bytes[len_offset + offset] = *byte;
|
||||
}
|
||||
let len = u16::try_from(bytes.len() - len_offset - 2)
|
||||
.map_err(|_| CodecError::LengthPrefixOverflow)?;
|
||||
bytes[len_offset..len_offset + 2].copy_from_slice(&len.to_be_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Decode `bytes` into a vector of `D` values, treating `bytes` as a [variable-length vector][1] of
|
||||
|
@ -330,20 +350,22 @@ pub fn encode_u24_items<P, E: ParameterizedEncode<P>>(
|
|||
bytes: &mut Vec<u8>,
|
||||
encoding_parameter: &P,
|
||||
items: &[E],
|
||||
) {
|
||||
) -> Result<(), CodecError> {
|
||||
// Reserve space to later write length
|
||||
let len_offset = bytes.len();
|
||||
U24(0).encode(bytes);
|
||||
U24(0).encode(bytes)?;
|
||||
|
||||
for item in items {
|
||||
item.encode_with_param(encoding_parameter, bytes);
|
||||
item.encode_with_param(encoding_parameter, bytes)?;
|
||||
}
|
||||
|
||||
let len = bytes.len() - len_offset - 3;
|
||||
assert!(len <= 0xffffff);
|
||||
for (offset, byte) in u32::to_be_bytes(len as u32)[1..].iter().enumerate() {
|
||||
bytes[len_offset + offset] = *byte;
|
||||
let len = u32::try_from(bytes.len() - len_offset - 3)
|
||||
.map_err(|_| CodecError::LengthPrefixOverflow)?;
|
||||
if len > 0xffffff {
|
||||
return Err(CodecError::LengthPrefixOverflow);
|
||||
}
|
||||
bytes[len_offset..len_offset + 3].copy_from_slice(&len.to_be_bytes()[1..]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Decode `bytes` into a vector of `D` values, treating `bytes` as a [variable-length vector][1] of
|
||||
|
@ -368,20 +390,19 @@ pub fn encode_u32_items<P, E: ParameterizedEncode<P>>(
|
|||
bytes: &mut Vec<u8>,
|
||||
encoding_parameter: &P,
|
||||
items: &[E],
|
||||
) {
|
||||
) -> Result<(), CodecError> {
|
||||
// Reserve space to later write length
|
||||
let len_offset = bytes.len();
|
||||
0u32.encode(bytes);
|
||||
0u32.encode(bytes)?;
|
||||
|
||||
for item in items {
|
||||
item.encode_with_param(encoding_parameter, bytes);
|
||||
item.encode_with_param(encoding_parameter, bytes)?;
|
||||
}
|
||||
|
||||
let len = bytes.len() - len_offset - 4;
|
||||
let len: u32 = len.try_into().expect("Length too large");
|
||||
for (offset, byte) in len.to_be_bytes().iter().enumerate() {
|
||||
bytes[len_offset + offset] = *byte;
|
||||
}
|
||||
let len = u32::try_from(bytes.len() - len_offset - 4)
|
||||
.map_err(|_| CodecError::LengthPrefixOverflow)?;
|
||||
bytes[len_offset..len_offset + 4].copy_from_slice(&len.to_be_bytes());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Decode `bytes` into a vector of `D` values, treating `bytes` as a [variable-length vector][1] of
|
||||
|
@ -432,6 +453,7 @@ fn decode_items<P, D: ParameterizedDecode<P>>(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::io::ErrorKind;
|
||||
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
|
@ -439,7 +461,7 @@ mod tests {
|
|||
#[test]
|
||||
fn encode_nothing() {
|
||||
let mut bytes = vec![];
|
||||
().encode(&mut bytes);
|
||||
().encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 0);
|
||||
}
|
||||
|
||||
|
@ -448,7 +470,7 @@ mod tests {
|
|||
let value = 100u8;
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 1);
|
||||
|
||||
let decoded = u8::decode(&mut Cursor::new(&bytes)).unwrap();
|
||||
|
@ -460,7 +482,7 @@ mod tests {
|
|||
let value = 1000u16;
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 2);
|
||||
// Check endianness of encoding
|
||||
assert_eq!(bytes, vec![3, 232]);
|
||||
|
@ -474,7 +496,7 @@ mod tests {
|
|||
let value = U24(1_000_000u32);
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 3);
|
||||
// Check endianness of encoding
|
||||
assert_eq!(bytes, vec![15, 66, 64]);
|
||||
|
@ -488,7 +510,7 @@ mod tests {
|
|||
let value = 134_217_728u32;
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 4);
|
||||
// Check endianness of encoding
|
||||
assert_eq!(bytes, vec![8, 0, 0, 0]);
|
||||
|
@ -502,7 +524,7 @@ mod tests {
|
|||
let value = 137_438_953_472u64;
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), 8);
|
||||
// Check endianness of encoding
|
||||
assert_eq!(bytes, vec![0, 0, 0, 32, 0, 0, 0, 0]);
|
||||
|
@ -521,12 +543,12 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Encode for TestMessage {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.field_u8.encode(bytes);
|
||||
self.field_u16.encode(bytes);
|
||||
self.field_u24.encode(bytes);
|
||||
self.field_u32.encode(bytes);
|
||||
self.field_u64.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.field_u8.encode(bytes)?;
|
||||
self.field_u16.encode(bytes)?;
|
||||
self.field_u24.encode(bytes)?;
|
||||
self.field_u32.encode(bytes)?;
|
||||
self.field_u64.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -584,7 +606,7 @@ mod tests {
|
|||
};
|
||||
|
||||
let mut bytes = vec![];
|
||||
value.encode(&mut bytes);
|
||||
value.encode(&mut bytes).unwrap();
|
||||
assert_eq!(bytes.len(), TestMessage::encoded_length());
|
||||
assert_eq!(value.encoded_len().unwrap(), TestMessage::encoded_length());
|
||||
|
||||
|
@ -622,7 +644,7 @@ mod tests {
|
|||
fn roundtrip_variable_length_u8() {
|
||||
let values = messages_vec();
|
||||
let mut bytes = vec![];
|
||||
encode_u8_items(&mut bytes, &(), &values);
|
||||
encode_u8_items(&mut bytes, &(), &values).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
bytes.len(),
|
||||
|
@ -640,7 +662,7 @@ mod tests {
|
|||
fn roundtrip_variable_length_u16() {
|
||||
let values = messages_vec();
|
||||
let mut bytes = vec![];
|
||||
encode_u16_items(&mut bytes, &(), &values);
|
||||
encode_u16_items(&mut bytes, &(), &values).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
bytes.len(),
|
||||
|
@ -661,7 +683,7 @@ mod tests {
|
|||
fn roundtrip_variable_length_u24() {
|
||||
let values = messages_vec();
|
||||
let mut bytes = vec![];
|
||||
encode_u24_items(&mut bytes, &(), &values);
|
||||
encode_u24_items(&mut bytes, &(), &values).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
bytes.len(),
|
||||
|
@ -682,7 +704,7 @@ mod tests {
|
|||
fn roundtrip_variable_length_u32() {
|
||||
let values = messages_vec();
|
||||
let mut bytes = Vec::new();
|
||||
encode_u32_items(&mut bytes, &(), &values);
|
||||
encode_u32_items(&mut bytes, &(), &values).unwrap();
|
||||
|
||||
assert_eq!(bytes.len(), 4 + 3 * TestMessage::encoded_length());
|
||||
|
||||
|
@ -696,6 +718,21 @@ mod tests {
|
|||
assert_eq!(values, decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_too_short() {
|
||||
let values = messages_vec();
|
||||
let mut bytes = Vec::new();
|
||||
encode_u32_items(&mut bytes, &(), &values).unwrap();
|
||||
|
||||
let error =
|
||||
decode_u32_items::<_, TestMessage>(&(), &mut Cursor::new(&bytes[..3])).unwrap_err();
|
||||
assert_matches!(error, CodecError::Io(e) => assert_eq!(e.kind(), ErrorKind::UnexpectedEof));
|
||||
|
||||
let error =
|
||||
decode_u32_items::<_, TestMessage>(&(), &mut Cursor::new(&bytes[..4])).unwrap_err();
|
||||
assert_matches!(error, CodecError::LengthPrefixTooBig(_));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_items_overflow() {
|
||||
let encoded = vec![1u8];
|
||||
|
@ -724,11 +761,56 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn length_hint_correctness() {
|
||||
assert_eq!(().encoded_len().unwrap(), ().get_encoded().len());
|
||||
assert_eq!(0u8.encoded_len().unwrap(), 0u8.get_encoded().len());
|
||||
assert_eq!(0u16.encoded_len().unwrap(), 0u16.get_encoded().len());
|
||||
assert_eq!(U24(0).encoded_len().unwrap(), U24(0).get_encoded().len());
|
||||
assert_eq!(0u32.encoded_len().unwrap(), 0u32.get_encoded().len());
|
||||
assert_eq!(0u64.encoded_len().unwrap(), 0u64.get_encoded().len());
|
||||
assert_eq!(().encoded_len().unwrap(), ().get_encoded().unwrap().len());
|
||||
assert_eq!(0u8.encoded_len().unwrap(), 0u8.get_encoded().unwrap().len());
|
||||
assert_eq!(
|
||||
0u16.encoded_len().unwrap(),
|
||||
0u16.get_encoded().unwrap().len()
|
||||
);
|
||||
assert_eq!(
|
||||
U24(0).encoded_len().unwrap(),
|
||||
U24(0).get_encoded().unwrap().len()
|
||||
);
|
||||
assert_eq!(
|
||||
0u32.encoded_len().unwrap(),
|
||||
0u32.get_encoded().unwrap().len()
|
||||
);
|
||||
assert_eq!(
|
||||
0u64.encoded_len().unwrap(),
|
||||
0u64.get_encoded().unwrap().len()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_decoded_leftover() {
|
||||
let encoded_good = [1, 2, 3, 4];
|
||||
assert_matches!(u32::get_decoded(&encoded_good).unwrap(), 0x01020304u32);
|
||||
|
||||
let encoded_bad = [1, 2, 3, 4, 5];
|
||||
let error = u32::get_decoded(&encoded_bad).unwrap_err();
|
||||
assert_matches!(error, CodecError::BytesLeftOver(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encoded_len_backwards_compatibility() {
|
||||
struct MyMessage;
|
||||
|
||||
impl Encode for MyMessage {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.extend_from_slice(b"Hello, world");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(MyMessage.encoded_len(), None);
|
||||
|
||||
assert_eq!(MyMessage.get_encoded().unwrap(), b"Hello, world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_length_prefix_overflow() {
|
||||
let mut bytes = Vec::new();
|
||||
let error = encode_u8_items(&mut bytes, &(), &[1u8; u8::MAX as usize + 1]).unwrap_err();
|
||||
assert_matches!(error, CodecError::LengthPrefixOverflow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
/// Errors propagated by methods in this module.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum DpError {
|
||||
/// Tried to use an invalid float as privacy parameter.
|
||||
#[error(
|
||||
|
|
|
@ -292,7 +292,7 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::dp::Rational;
|
||||
use crate::vdaf::xof::SeedStreamSha3;
|
||||
use crate::vdaf::xof::SeedStreamTurboShake128;
|
||||
|
||||
use num_bigint::{BigUint, Sign, ToBigInt, ToBigUint};
|
||||
use num_traits::{One, Signed, ToPrimitive};
|
||||
|
@ -306,15 +306,15 @@ mod tests {
|
|||
DiscreteGaussian::new(Ratio::<BigUint>::from_integer(BigUint::from(5u8))).unwrap();
|
||||
|
||||
// check samples are consistent
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let samples: Vec<i8> = (0..10)
|
||||
.map(|_| i8::try_from(sampler.sample(&mut rng)).unwrap())
|
||||
.collect();
|
||||
let samples1: Vec<i8> = (0..10)
|
||||
.map(|_| i8::try_from(sampler.sample(&mut rng)).unwrap())
|
||||
.collect();
|
||||
assert_eq!(samples, vec![-3, -11, -3, 5, 1, 5, 2, 2, 1, 18]);
|
||||
assert_eq!(samples1, vec![4, -4, -5, -2, 0, -5, -3, 1, 1, -2]);
|
||||
assert_eq!(samples, vec![0, -3, -2, 3, 2, -1, -5, 4, -7, -5]);
|
||||
assert_eq!(samples1, vec![2, 7, -8, -3, 1, -3, -3, 6, -3, -1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -325,7 +325,7 @@ mod tests {
|
|||
// sample from a manually created distribution
|
||||
let sampler1 =
|
||||
DiscreteGaussian::new(Ratio::<BigUint>::from_integer(BigUint::from(4u8))).unwrap();
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let samples1: Vec<i8> = (0..10)
|
||||
.map(|_| i8::try_from(sampler1.sample(&mut rng)).unwrap())
|
||||
.collect();
|
||||
|
@ -337,7 +337,7 @@ mod tests {
|
|||
let sampler2 = zcdp
|
||||
.create_distribution(Ratio::<BigUint>::from_integer(1u8.into()))
|
||||
.unwrap();
|
||||
let mut rng2 = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng2 = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let samples2: Vec<i8> = (0..10)
|
||||
.map(|_| i8::try_from(sampler2.sample(&mut rng2)).unwrap())
|
||||
.collect();
|
||||
|
@ -485,7 +485,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// collect that number of samples
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let samples: Vec<BigInt> = (1..n_samples)
|
||||
.map(|_| {
|
||||
sample_discrete_gaussian(&Ratio::<BigUint>::from_integer(sigma.clone()), &mut rng)
|
||||
|
@ -519,7 +519,7 @@ mod tests {
|
|||
#[test]
|
||||
fn empirical_test_gauss() {
|
||||
[100, 2000, 20000].iter().for_each(|p| {
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let sampler = || {
|
||||
sample_discrete_gaussian(
|
||||
&Ratio::<BigUint>::from_integer((*p).to_biguint().unwrap()),
|
||||
|
@ -541,7 +541,7 @@ mod tests {
|
|||
#[test]
|
||||
fn empirical_test_bernoulli_mean() {
|
||||
[2u8, 5u8, 7u8, 9u8].iter().for_each(|p| {
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let sampler = || {
|
||||
if sample_bernoulli(
|
||||
&Ratio::<BigUint>::new(BigUint::one(), (*p).into()),
|
||||
|
@ -565,7 +565,7 @@ mod tests {
|
|||
#[test]
|
||||
fn empirical_test_geometric_mean() {
|
||||
[2u8, 5u8, 7u8, 9u8].iter().for_each(|p| {
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let sampler = || {
|
||||
sample_geometric_exp(
|
||||
&Ratio::<BigUint>::new(BigUint::one(), (*p).into()),
|
||||
|
@ -588,7 +588,7 @@ mod tests {
|
|||
#[test]
|
||||
fn empirical_test_laplace_mean() {
|
||||
[2u8, 5u8, 7u8, 9u8].iter().for_each(|p| {
|
||||
let mut rng = SeedStreamSha3::from_seed([0u8; 16]);
|
||||
let mut rng = SeedStreamTurboShake128::from_seed([0u8; 16]);
|
||||
let sampler = || {
|
||||
sample_discrete_laplace(
|
||||
&Ratio::<BigUint>::new(BigUint::one(), (*p).into()),
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::convert::TryFrom;
|
|||
|
||||
/// An error returned by an FFT operation.
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum FftError {
|
||||
/// The output is too small.
|
||||
#[error("output slice is smaller than specified size")]
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//! [`FftFriendlyFieldElement`], and have an associated element called the "generator" that
|
||||
//! generates a multiplicative subgroup of order `2^n` for some `n`.
|
||||
|
||||
#[cfg(feature = "crypto-dependencies")]
|
||||
use crate::prng::{Prng, PrngError};
|
||||
use crate::{
|
||||
codec::{CodecError, Decode, Encode},
|
||||
|
@ -25,8 +24,8 @@ use std::{
|
|||
io::{Cursor, Read},
|
||||
marker::PhantomData,
|
||||
ops::{
|
||||
Add, AddAssign, BitAnd, ControlFlow, Div, DivAssign, Mul, MulAssign, Neg, Shl, Shr, Sub,
|
||||
SubAssign,
|
||||
Add, AddAssign, BitAnd, ControlFlow, Div, DivAssign, Mul, MulAssign, Neg, Range, Shl, Shr,
|
||||
Sub, SubAssign,
|
||||
},
|
||||
};
|
||||
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};
|
||||
|
@ -39,6 +38,7 @@ pub use field255::Field255;
|
|||
|
||||
/// Possible errors from finite field operations.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum FieldError {
|
||||
/// Input sizes do not match.
|
||||
#[error("input sizes do not match")]
|
||||
|
@ -46,19 +46,24 @@ pub enum FieldError {
|
|||
/// Returned when decoding a [`FieldElement`] from a too-short byte string.
|
||||
#[error("short read from bytes")]
|
||||
ShortRead,
|
||||
/// Returned when decoding a [`FieldElement`] from a byte string that encodes an integer greater
|
||||
/// than or equal to the field modulus.
|
||||
#[error("read from byte slice exceeds modulus")]
|
||||
/// Returned when converting an integer to a [`FieldElement`] if the integer is greater than or
|
||||
/// equal to the field modulus.
|
||||
#[error("input value exceeds modulus")]
|
||||
ModulusOverflow,
|
||||
/// Error while performing I/O.
|
||||
#[error("I/O error")]
|
||||
Io(#[from] std::io::Error),
|
||||
/// Error encoding or decoding a field.
|
||||
#[error("Codec error")]
|
||||
Codec(#[from] CodecError),
|
||||
#[deprecated]
|
||||
Codec(CodecError),
|
||||
/// Error converting to [`FieldElementWithInteger::Integer`].
|
||||
#[error("Integer TryFrom error")]
|
||||
IntegerTryFrom,
|
||||
/// Returned when encoding an integer to "bitvector representation", or decoding from the same,
|
||||
/// if the number of bits is larger than the bit length of the field's modulus.
|
||||
#[error("bit vector length exceeds modulus bit length")]
|
||||
BitVectorTooLong,
|
||||
}
|
||||
|
||||
/// Objects with this trait represent an element of `GF(p)` for some prime `p`.
|
||||
|
@ -100,8 +105,8 @@ pub trait FieldElement:
|
|||
fn inv(&self) -> Self;
|
||||
|
||||
/// Interprets the next [`Self::ENCODED_SIZE`] bytes from the input slice as an element of the
|
||||
/// field. The `m` most significant bits are cleared, where `m` is equal to the length of
|
||||
/// [`Self::Integer`] in bits minus the length of the modulus in bits.
|
||||
/// field. Any of the most significant bits beyond the bit length of the modulus will be
|
||||
/// cleared, in order to minimize the amount of rejection sampling needed.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -110,9 +115,9 @@ pub trait FieldElement:
|
|||
///
|
||||
/// # Warnings
|
||||
///
|
||||
/// This function should only be used within [`prng::Prng`] to convert a random byte string into
|
||||
/// a field element. Use [`Self::decode`] to deserialize field elements. Use
|
||||
/// [`field::rand`] or [`prng::Prng`] to randomly generate field elements.
|
||||
/// This function should only be used internally to convert a random byte string into
|
||||
/// a field element. Use [`Decode::decode`] to deserialize field elements. Use
|
||||
/// [`random_vector`] to randomly generate field elements.
|
||||
#[doc(hidden)]
|
||||
fn try_from_random(bytes: &[u8]) -> Result<Self, FieldError>;
|
||||
|
||||
|
@ -129,9 +134,10 @@ pub trait FieldElement:
|
|||
/// Ideally we would implement `From<&[F: FieldElement]> for Vec<u8>` or the corresponding
|
||||
/// `Into`, but the orphan rule and the stdlib's blanket implementations of `Into` make this
|
||||
/// impossible.
|
||||
#[deprecated]
|
||||
fn slice_into_byte_vec(values: &[Self]) -> Vec<u8> {
|
||||
let mut vec = Vec::with_capacity(values.len() * Self::ENCODED_SIZE);
|
||||
encode_fieldvec(values, &mut vec);
|
||||
encode_fieldvec(values, &mut vec).unwrap();
|
||||
vec
|
||||
}
|
||||
|
||||
|
@ -149,18 +155,49 @@ pub trait FieldElement:
|
|||
/// Ideally we would implement `From<&[u8]> for Vec<F: FieldElement>` or the corresponding
|
||||
/// `Into`, but the orphan rule and the stdlib's blanket implementations of `Into` make this
|
||||
/// impossible.
|
||||
#[deprecated]
|
||||
fn byte_slice_into_vec(bytes: &[u8]) -> Result<Vec<Self>, FieldError> {
|
||||
if bytes.len() % Self::ENCODED_SIZE != 0 {
|
||||
return Err(FieldError::ShortRead);
|
||||
}
|
||||
let mut vec = Vec::with_capacity(bytes.len() / Self::ENCODED_SIZE);
|
||||
for chunk in bytes.chunks_exact(Self::ENCODED_SIZE) {
|
||||
vec.push(Self::get_decoded(chunk)?);
|
||||
#[allow(deprecated)]
|
||||
vec.push(Self::get_decoded(chunk).map_err(FieldError::Codec)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
/// An integer type that accompanies a finite field. Integers and field elements may be converted
|
||||
/// back and forth via the natural map between residue classes modulo 'p' and integers between 0
|
||||
/// and p - 1.
|
||||
pub trait Integer:
|
||||
Debug
|
||||
+ Eq
|
||||
+ Ord
|
||||
+ BitAnd<Output = Self>
|
||||
+ Div<Output = Self>
|
||||
+ Shl<usize, Output = Self>
|
||||
+ Shr<usize, Output = Self>
|
||||
+ Add<Output = Self>
|
||||
+ Sub<Output = Self>
|
||||
+ TryFrom<usize, Error = Self::TryFromUsizeError>
|
||||
+ TryInto<u64, Error = Self::TryIntoU64Error>
|
||||
{
|
||||
/// The error returned if converting `usize` to this integer type fails.
|
||||
type TryFromUsizeError: std::error::Error;
|
||||
|
||||
/// The error returned if converting this integer type to a `u64` fails.
|
||||
type TryIntoU64Error: std::error::Error;
|
||||
|
||||
/// Returns zero.
|
||||
fn zero() -> Self;
|
||||
|
||||
/// Returns one.
|
||||
fn one() -> Self;
|
||||
}
|
||||
|
||||
/// Extension trait for field elements that can be converted back and forth to an integer type.
|
||||
///
|
||||
/// The `Integer` associated type is an integer (primitive or otherwise) that supports various
|
||||
|
@ -168,104 +205,95 @@ pub trait FieldElement:
|
|||
/// integer type. This trait also defines methods on field elements, `pow` and `modulus`, that make
|
||||
/// use of the associated integer type.
|
||||
pub trait FieldElementWithInteger: FieldElement + From<Self::Integer> {
|
||||
/// The error returned if converting `usize` to an `Integer` fails.
|
||||
type IntegerTryFromError: std::error::Error;
|
||||
|
||||
/// The error returned if converting an `Integer` to a `u64` fails.
|
||||
type TryIntoU64Error: std::error::Error;
|
||||
|
||||
/// The integer representation of a field element.
|
||||
type Integer: Copy
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Ord
|
||||
+ BitAnd<Output = Self::Integer>
|
||||
+ Div<Output = Self::Integer>
|
||||
+ Shl<usize, Output = Self::Integer>
|
||||
+ Shr<usize, Output = Self::Integer>
|
||||
+ Add<Output = Self::Integer>
|
||||
+ Sub<Output = Self::Integer>
|
||||
+ From<Self>
|
||||
+ TryFrom<usize, Error = Self::IntegerTryFromError>
|
||||
+ TryInto<u64, Error = Self::TryIntoU64Error>;
|
||||
type Integer: Integer + From<Self> + Copy;
|
||||
|
||||
/// Modular exponentation, i.e., `self^exp (mod p)`.
|
||||
fn pow(&self, exp: Self::Integer) -> Self;
|
||||
|
||||
/// Returns the prime modulus `p`.
|
||||
fn modulus() -> Self::Integer;
|
||||
/// Encode the integer `input` as a sequence of bits in two's complement representation, least
|
||||
/// significant bit first, and then map each bit to a field element.
|
||||
///
|
||||
/// Returns an error if `input` cannot be represented with `bits` many bits, or if `bits`
|
||||
/// is larger than the bit width of the field's modulus.
|
||||
fn encode_as_bitvector(
|
||||
input: Self::Integer,
|
||||
bits: usize,
|
||||
) -> Result<BitvectorRepresentationIter<Self>, FieldError> {
|
||||
// Check if `bits` is too large for this field.
|
||||
if !Self::valid_integer_bitlength(bits) {
|
||||
return Err(FieldError::BitVectorTooLong);
|
||||
}
|
||||
|
||||
// Check if the input value can be represented in the requested number of bits by shifting
|
||||
// it. The above check on `bits` ensures this shift won't panic due to the shift width
|
||||
// being too large.
|
||||
if input >> bits != Self::Integer::zero() {
|
||||
return Err(FieldError::InputSizeMismatch);
|
||||
}
|
||||
|
||||
Ok(BitvectorRepresentationIter {
|
||||
inner: 0..bits,
|
||||
input,
|
||||
})
|
||||
}
|
||||
|
||||
/// Inverts the encoding done by [`Self::encode_as_bitvector`], and returns a single field
|
||||
/// element.
|
||||
///
|
||||
/// This performs an inner product between the input vector of field elements and successive
|
||||
/// powers of two (starting with 2^0 = 1). If the input came from [`Self::encode_as_bitvector`],
|
||||
/// then the result will be equal to the originally encoded integer, projected into the field.
|
||||
///
|
||||
/// Note that this decoding operation is linear, so it can be applied to secret shares of an
|
||||
/// encoded integer, and if the results are summed up, it will be equal to the encoded integer.
|
||||
///
|
||||
/// Returns an error if the length of the input is larger than the bit width of the field's
|
||||
/// modulus.
|
||||
fn decode_bitvector(input: &[Self]) -> Result<Self, FieldError> {
|
||||
if !Self::valid_integer_bitlength(input.len()) {
|
||||
return Err(FieldError::BitVectorTooLong);
|
||||
}
|
||||
|
||||
let mut decoded = Self::zero();
|
||||
let one = Self::one();
|
||||
let two = one + one;
|
||||
let mut power_of_two = one;
|
||||
for value in input.iter() {
|
||||
decoded += *value * power_of_two;
|
||||
power_of_two *= two;
|
||||
}
|
||||
Ok(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
/// This iterator returns a sequence of field elements that are equal to zero or one, representing
|
||||
/// some integer in two's complement form. See [`FieldElementWithInteger::encode_as_bitvector`].
|
||||
// Note that this is implemented with a separate struct, instead of using the map combinator,
|
||||
// because return_position_impl_trait_in_trait is not yet stable.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BitvectorRepresentationIter<F: FieldElementWithInteger> {
|
||||
inner: Range<usize>,
|
||||
input: F::Integer,
|
||||
}
|
||||
|
||||
impl<F> Iterator for BitvectorRepresentationIter<F>
|
||||
where
|
||||
F: FieldElementWithInteger,
|
||||
{
|
||||
type Item = F;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let bit_offset = self.inner.next()?;
|
||||
Some(F::from((self.input >> bit_offset) & F::Integer::one()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods common to all `FieldElementWithInteger` implementations that are private to the crate.
|
||||
pub(crate) trait FieldElementWithIntegerExt: FieldElementWithInteger {
|
||||
/// Encode `input` as bitvector of elements of `Self`. Output is written into the `output` slice.
|
||||
/// If `output.len()` is smaller than the number of bits required to respresent `input`,
|
||||
/// an error is returned.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `input` - The field element to encode
|
||||
/// * `output` - The slice to write the encoded bits into. Least signicant bit comes first
|
||||
fn fill_with_bitvector_representation(
|
||||
input: &Self::Integer,
|
||||
output: &mut [Self],
|
||||
) -> Result<(), FieldError> {
|
||||
// Create a mutable copy of `input`. In each iteration of the following loop we take the
|
||||
// least significant bit, and shift input to the right by one bit.
|
||||
let mut i = *input;
|
||||
|
||||
let one = Self::Integer::from(Self::one());
|
||||
for bit in output.iter_mut() {
|
||||
let w = Self::from(i & one);
|
||||
*bit = w;
|
||||
i = i >> 1;
|
||||
}
|
||||
|
||||
// If `i` is still not zero, this means that it cannot be encoded by `bits` bits.
|
||||
if i != Self::Integer::from(Self::zero()) {
|
||||
return Err(FieldError::InputSizeMismatch);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Encode `input` as `bits`-bit vector of elements of `Self` if it's small enough
|
||||
/// to be represented with that many bits.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `input` - The field element to encode
|
||||
/// * `bits` - The number of bits to use for the encoding
|
||||
fn encode_into_bitvector_representation(
|
||||
input: &Self::Integer,
|
||||
bits: usize,
|
||||
) -> Result<Vec<Self>, FieldError> {
|
||||
let mut result = vec![Self::zero(); bits];
|
||||
Self::fill_with_bitvector_representation(input, &mut result)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Decode the bitvector-represented value `input` into a simple representation as a single
|
||||
/// field element.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function errors if `2^input.len() - 1` does not fit into the field `Self`.
|
||||
fn decode_from_bitvector_representation(input: &[Self]) -> Result<Self, FieldError> {
|
||||
let fi_one = Self::Integer::from(Self::one());
|
||||
|
||||
if !Self::valid_integer_bitlength(input.len()) {
|
||||
return Err(FieldError::ModulusOverflow);
|
||||
}
|
||||
|
||||
let mut decoded = Self::zero();
|
||||
for (l, bit) in input.iter().enumerate() {
|
||||
let w = fi_one << l;
|
||||
decoded += Self::from(w) * *bit;
|
||||
}
|
||||
Ok(decoded)
|
||||
}
|
||||
|
||||
/// Interpret `i` as [`Self::Integer`] if it's representable in that type and smaller than the
|
||||
/// field modulus.
|
||||
fn valid_integer_try_from<N>(i: N) -> Result<Self::Integer, FieldError>
|
||||
|
@ -285,7 +313,7 @@ pub(crate) trait FieldElementWithIntegerExt: FieldElementWithInteger {
|
|||
if bits >= 8 * Self::ENCODED_SIZE {
|
||||
return false;
|
||||
}
|
||||
if Self::modulus() >> bits != Self::Integer::from(Self::zero()) {
|
||||
if Self::modulus() >> bits != Self::Integer::zero() {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
|
@ -382,7 +410,7 @@ macro_rules! make_field {
|
|||
///
|
||||
/// As an invariant, this integer representing the field element in the Montgomery domain
|
||||
/// must be less than the field modulus, `p`.
|
||||
#[derive(Clone, Copy, PartialOrd, Ord, Default)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct $elem(u128);
|
||||
|
||||
impl $elem {
|
||||
|
@ -640,9 +668,10 @@ macro_rules! make_field {
|
|||
}
|
||||
|
||||
impl Encode for $elem {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
let slice = <[u8; $elem::ENCODED_SIZE]>::from(*self);
|
||||
bytes.extend_from_slice(&slice);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -683,8 +712,6 @@ macro_rules! make_field {
|
|||
|
||||
impl FieldElementWithInteger for $elem {
|
||||
type Integer = $int;
|
||||
type IntegerTryFromError = <Self::Integer as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self::Integer as TryInto<u64>>::Error;
|
||||
|
||||
fn pow(&self, exp: Self::Integer) -> Self {
|
||||
// FieldParameters::pow() relies on mul(), and will always return a value less
|
||||
|
@ -717,6 +744,45 @@ macro_rules! make_field {
|
|||
};
|
||||
}
|
||||
|
||||
impl Integer for u32 {
|
||||
type TryFromUsizeError = <Self as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self as TryInto<u64>>::Error;
|
||||
|
||||
fn zero() -> Self {
|
||||
0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl Integer for u64 {
|
||||
type TryFromUsizeError = <Self as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self as TryInto<u64>>::Error;
|
||||
|
||||
fn zero() -> Self {
|
||||
0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl Integer for u128 {
|
||||
type TryFromUsizeError = <Self as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self as TryInto<u64>>::Error;
|
||||
|
||||
fn zero() -> Self {
|
||||
0
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
make_field!(
|
||||
/// Same as Field32, but encoded in little endian for compatibility with Prio v2.
|
||||
FieldPrio2,
|
||||
|
@ -761,7 +827,7 @@ pub(crate) fn merge_vector<F: FieldElement>(
|
|||
}
|
||||
|
||||
/// Outputs an additive secret sharing of the input.
|
||||
#[cfg(all(feature = "crypto-dependencies", test))]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn split_vector<F: FieldElement>(
|
||||
inp: &[F],
|
||||
num_shares: usize,
|
||||
|
@ -785,18 +851,20 @@ pub(crate) fn split_vector<F: FieldElement>(
|
|||
}
|
||||
|
||||
/// Generate a vector of uniformly distributed random field elements.
|
||||
#[cfg(feature = "crypto-dependencies")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "crypto-dependencies")))]
|
||||
pub fn random_vector<F: FieldElement>(len: usize) -> Result<Vec<F>, PrngError> {
|
||||
Ok(Prng::new()?.take(len).collect())
|
||||
}
|
||||
|
||||
/// `encode_fieldvec` serializes a type that is equivalent to a vector of field elements.
|
||||
#[inline(always)]
|
||||
pub(crate) fn encode_fieldvec<F: FieldElement, T: AsRef<[F]>>(val: T, bytes: &mut Vec<u8>) {
|
||||
pub(crate) fn encode_fieldvec<F: FieldElement, T: AsRef<[F]>>(
|
||||
val: T,
|
||||
bytes: &mut Vec<u8>,
|
||||
) -> Result<(), CodecError> {
|
||||
for elem in val.as_ref() {
|
||||
elem.encode(bytes);
|
||||
elem.encode(bytes)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `decode_fieldvec` deserializes some number of field elements from a cursor, and advances the
|
||||
|
@ -822,16 +890,14 @@ pub(crate) fn decode_fieldvec<F: FieldElement>(
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_utils {
|
||||
use super::{FieldElement, FieldElementWithInteger};
|
||||
use super::{FieldElement, FieldElementWithInteger, Integer};
|
||||
use crate::{codec::CodecError, field::FieldError, prng::Prng};
|
||||
use assert_matches::assert_matches;
|
||||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
convert::{TryFrom, TryInto},
|
||||
fmt::Debug,
|
||||
convert::TryFrom,
|
||||
hash::{Hash, Hasher},
|
||||
io::Cursor,
|
||||
ops::{Add, BitAnd, Div, Shl, Shr, Sub},
|
||||
};
|
||||
|
||||
/// A test-only copy of `FieldElementWithInteger`.
|
||||
|
@ -842,42 +908,30 @@ pub(crate) mod test_utils {
|
|||
/// requires the `Integer` associated type satisfy `Clone`, not `Copy`, so that it may be used
|
||||
/// with arbitrary precision integer implementations.
|
||||
pub(crate) trait TestFieldElementWithInteger:
|
||||
FieldElement + From<Self::Integer>
|
||||
FieldElement + From<Self::TestInteger>
|
||||
{
|
||||
type IntegerTryFromError: std::error::Error;
|
||||
type TryIntoU64Error: std::error::Error;
|
||||
type Integer: Clone
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Ord
|
||||
+ BitAnd<Output = Self::Integer>
|
||||
+ Div<Output = Self::Integer>
|
||||
+ Shl<usize, Output = Self::Integer>
|
||||
+ Shr<usize, Output = Self::Integer>
|
||||
+ Add<Output = Self::Integer>
|
||||
+ Sub<Output = Self::Integer>
|
||||
+ From<Self>
|
||||
+ TryFrom<usize, Error = Self::IntegerTryFromError>
|
||||
+ TryInto<u64, Error = Self::TryIntoU64Error>;
|
||||
type TestInteger: Integer + From<Self> + Clone;
|
||||
|
||||
fn pow(&self, exp: Self::Integer) -> Self;
|
||||
fn pow(&self, exp: Self::TestInteger) -> Self;
|
||||
|
||||
fn modulus() -> Self::Integer;
|
||||
fn modulus() -> Self::TestInteger;
|
||||
}
|
||||
|
||||
impl<F> TestFieldElementWithInteger for F
|
||||
where
|
||||
F: FieldElementWithInteger,
|
||||
{
|
||||
type IntegerTryFromError = <F as FieldElementWithInteger>::IntegerTryFromError;
|
||||
type TryIntoU64Error = <F as FieldElementWithInteger>::TryIntoU64Error;
|
||||
type Integer = <F as FieldElementWithInteger>::Integer;
|
||||
type IntegerTryFromError = <F::Integer as Integer>::TryFromUsizeError;
|
||||
type TryIntoU64Error = <F::Integer as Integer>::TryIntoU64Error;
|
||||
type TestInteger = F::Integer;
|
||||
|
||||
fn pow(&self, exp: Self::Integer) -> Self {
|
||||
fn pow(&self, exp: Self::TestInteger) -> Self {
|
||||
<F as FieldElementWithInteger>::pow(self, exp)
|
||||
}
|
||||
|
||||
fn modulus() -> Self::Integer {
|
||||
fn modulus() -> Self::TestInteger {
|
||||
<F as FieldElementWithInteger>::modulus()
|
||||
}
|
||||
}
|
||||
|
@ -885,11 +939,11 @@ pub(crate) mod test_utils {
|
|||
pub(crate) fn field_element_test_common<F: TestFieldElementWithInteger>() {
|
||||
let mut prng: Prng<F, _> = Prng::new().unwrap();
|
||||
let int_modulus = F::modulus();
|
||||
let int_one = F::Integer::try_from(1).unwrap();
|
||||
let int_one = F::TestInteger::try_from(1).unwrap();
|
||||
let zero = F::zero();
|
||||
let one = F::one();
|
||||
let two = F::from(F::Integer::try_from(2).unwrap());
|
||||
let four = F::from(F::Integer::try_from(4).unwrap());
|
||||
let two = F::from(F::TestInteger::try_from(2).unwrap());
|
||||
let four = F::from(F::TestInteger::try_from(4).unwrap());
|
||||
|
||||
// add
|
||||
assert_eq!(F::from(int_modulus.clone() - int_one.clone()) + one, zero);
|
||||
|
@ -943,10 +997,22 @@ pub(crate) mod test_utils {
|
|||
assert_eq!(a, c);
|
||||
|
||||
// integer conversion
|
||||
assert_eq!(F::Integer::from(zero), F::Integer::try_from(0).unwrap());
|
||||
assert_eq!(F::Integer::from(one), F::Integer::try_from(1).unwrap());
|
||||
assert_eq!(F::Integer::from(two), F::Integer::try_from(2).unwrap());
|
||||
assert_eq!(F::Integer::from(four), F::Integer::try_from(4).unwrap());
|
||||
assert_eq!(
|
||||
F::TestInteger::from(zero),
|
||||
F::TestInteger::try_from(0).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
F::TestInteger::from(one),
|
||||
F::TestInteger::try_from(1).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
F::TestInteger::from(two),
|
||||
F::TestInteger::try_from(2).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
F::TestInteger::from(four),
|
||||
F::TestInteger::try_from(4).unwrap()
|
||||
);
|
||||
|
||||
// serialization
|
||||
let test_inputs = vec![
|
||||
|
@ -957,7 +1023,7 @@ pub(crate) mod test_utils {
|
|||
];
|
||||
for want in test_inputs.iter() {
|
||||
let mut bytes = vec![];
|
||||
want.encode(&mut bytes);
|
||||
want.encode(&mut bytes).unwrap();
|
||||
|
||||
assert_eq!(bytes.len(), F::ENCODED_SIZE);
|
||||
assert_eq!(want.encoded_len().unwrap(), F::ENCODED_SIZE);
|
||||
|
@ -966,9 +1032,12 @@ pub(crate) mod test_utils {
|
|||
assert_eq!(got, *want);
|
||||
}
|
||||
|
||||
let serialized_vec = F::slice_into_byte_vec(&test_inputs);
|
||||
let deserialized = F::byte_slice_into_vec(&serialized_vec).unwrap();
|
||||
assert_eq!(deserialized, test_inputs);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
let serialized_vec = F::slice_into_byte_vec(&test_inputs);
|
||||
let deserialized = F::byte_slice_into_vec(&serialized_vec).unwrap();
|
||||
assert_eq!(deserialized, test_inputs);
|
||||
}
|
||||
|
||||
let test_input = prng.get();
|
||||
let json = serde_json::to_string(&test_input).unwrap();
|
||||
|
@ -981,13 +1050,16 @@ pub(crate) mod test_utils {
|
|||
element.as_u64().unwrap();
|
||||
}
|
||||
|
||||
let err = F::byte_slice_into_vec(&[0]).unwrap_err();
|
||||
assert_matches!(err, FieldError::ShortRead);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
let err = F::byte_slice_into_vec(&[0]).unwrap_err();
|
||||
assert_matches!(err, FieldError::ShortRead);
|
||||
|
||||
let err = F::byte_slice_into_vec(&vec![0xffu8; F::ENCODED_SIZE]).unwrap_err();
|
||||
assert_matches!(err, FieldError::Codec(CodecError::Other(err)) => {
|
||||
assert_matches!(err.downcast_ref::<FieldError>(), Some(FieldError::ModulusOverflow));
|
||||
});
|
||||
let err = F::byte_slice_into_vec(&vec![0xffu8; F::ENCODED_SIZE]).unwrap_err();
|
||||
assert_matches!(err, FieldError::Codec(CodecError::Other(err)) => {
|
||||
assert_matches!(err.downcast_ref::<FieldError>(), Some(FieldError::ModulusOverflow));
|
||||
});
|
||||
}
|
||||
|
||||
let insufficient = vec![0u8; F::ENCODED_SIZE - 1];
|
||||
let err = F::try_from(insufficient.as_ref()).unwrap_err();
|
||||
|
@ -1004,7 +1076,7 @@ pub(crate) mod test_utils {
|
|||
// various products that should be equal have the same hash. Three is chosen as a generator
|
||||
// here because it happens to generate fairly large subgroups of (Z/pZ)* for all four
|
||||
// primes.
|
||||
let three = F::from(F::Integer::try_from(3).unwrap());
|
||||
let three = F::from(F::TestInteger::try_from(3).unwrap());
|
||||
let mut powers_of_three = Vec::with_capacity(500);
|
||||
let mut power = one;
|
||||
for _ in 0..500 {
|
||||
|
@ -1169,22 +1241,19 @@ mod tests {
|
|||
fn test_encode_into_bitvector() {
|
||||
let zero = Field128::zero();
|
||||
let one = Field128::one();
|
||||
let zero_enc = Field128::encode_into_bitvector_representation(&0, 4).unwrap();
|
||||
let one_enc = Field128::encode_into_bitvector_representation(&1, 4).unwrap();
|
||||
let fifteen_enc = Field128::encode_into_bitvector_representation(&15, 4).unwrap();
|
||||
let zero_enc = Field128::encode_as_bitvector(0, 4)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
let one_enc = Field128::encode_as_bitvector(1, 4)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
let fifteen_enc = Field128::encode_as_bitvector(15, 4)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(zero_enc, [zero; 4]);
|
||||
assert_eq!(one_enc, [one, zero, zero, zero]);
|
||||
assert_eq!(fifteen_enc, [one; 4]);
|
||||
Field128::encode_into_bitvector_representation(&16, 4).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fill_bitvector() {
|
||||
let zero = Field128::zero();
|
||||
let one = Field128::one();
|
||||
let mut output: Vec<Field128> = vec![zero; 6];
|
||||
Field128::fill_with_bitvector_representation(&9, &mut output[1..5]).unwrap();
|
||||
assert_eq!(output, [zero, one, zero, zero, one, zero]);
|
||||
Field128::fill_with_bitvector_representation(&16, &mut output[1..5]).unwrap_err();
|
||||
Field128::encode_as_bitvector(16, 4).unwrap_err();
|
||||
Field128::encode_as_bitvector(0, 129).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,8 +271,9 @@ impl<'de> Deserialize<'de> for Field255 {
|
|||
}
|
||||
|
||||
impl Encode for Field255 {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
bytes.extend_from_slice(&<[u8; Self::ENCODED_SIZE]>::from(*self));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -341,7 +342,7 @@ mod tests {
|
|||
codec::Encode,
|
||||
field::{
|
||||
test_utils::{field_element_test_common, TestFieldElementWithInteger},
|
||||
FieldElement, FieldError,
|
||||
FieldElement, FieldError, Integer,
|
||||
},
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
|
@ -375,16 +376,30 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
impl TestFieldElementWithInteger for Field255 {
|
||||
type Integer = BigUint;
|
||||
type IntegerTryFromError = <Self::Integer as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self::Integer as TryInto<u64>>::Error;
|
||||
impl Integer for BigUint {
|
||||
type TryFromUsizeError = <Self as TryFrom<usize>>::Error;
|
||||
|
||||
fn pow(&self, _exp: Self::Integer) -> Self {
|
||||
type TryIntoU64Error = <Self as TryInto<u64>>::Error;
|
||||
|
||||
fn zero() -> Self {
|
||||
Self::new(Vec::new())
|
||||
}
|
||||
|
||||
fn one() -> Self {
|
||||
Self::new(Vec::from([1]))
|
||||
}
|
||||
}
|
||||
|
||||
impl TestFieldElementWithInteger for Field255 {
|
||||
type TestInteger = BigUint;
|
||||
type IntegerTryFromError = <Self::TestInteger as TryFrom<usize>>::Error;
|
||||
type TryIntoU64Error = <Self::TestInteger as TryInto<u64>>::Error;
|
||||
|
||||
fn pow(&self, _exp: Self::TestInteger) -> Self {
|
||||
unimplemented!("Field255::pow() is not implemented because it's not needed yet")
|
||||
}
|
||||
|
||||
fn modulus() -> Self::Integer {
|
||||
fn modulus() -> Self::TestInteger {
|
||||
MODULUS.clone()
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +430,7 @@ mod tests {
|
|||
#[test]
|
||||
fn encode_endianness() {
|
||||
let mut one_encoded = Vec::new();
|
||||
Field255::one().encode(&mut one_encoded);
|
||||
Field255::one().encode(&mut one_encoded).unwrap();
|
||||
assert_eq!(
|
||||
one_encoded,
|
||||
[
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! Implementation of the generic Fully Linear Proof (FLP) system specified in
|
||||
//! [[draft-irtf-cfrg-vdaf-07]]. This is the main building block of [`Prio3`](crate::vdaf::prio3).
|
||||
//! [[draft-irtf-cfrg-vdaf-08]]. This is the main building block of [`Prio3`](crate::vdaf::prio3).
|
||||
//!
|
||||
//! The FLP is derived for any implementation of the [`Type`] trait. Such an implementation
|
||||
//! specifies a validity circuit that defines the set of valid measurements, as well as the finite
|
||||
|
@ -24,7 +24,7 @@
|
|||
//!
|
||||
//! // The prover chooses a measurement.
|
||||
//! let count = Count::new();
|
||||
//! let input: Vec<Field64> = count.encode_measurement(&0).unwrap();
|
||||
//! let input: Vec<Field64> = count.encode_measurement(&false).unwrap();
|
||||
//!
|
||||
//! // The prover and verifier agree on "joint randomness" used to generate and
|
||||
//! // check the proof. The application needs to ensure that the prover
|
||||
|
@ -44,7 +44,7 @@
|
|||
//! assert!(count.decide(&verifier).unwrap());
|
||||
//! ```
|
||||
//!
|
||||
//! [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
//! [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
use crate::dp::DifferentialPrivacyStrategy;
|
||||
|
@ -61,6 +61,7 @@ pub mod types;
|
|||
|
||||
/// Errors propagated by methods in this module.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum FlpError {
|
||||
/// Calling [`Type::prove`] returned an error.
|
||||
#[error("prove error: {0}")]
|
||||
|
@ -110,20 +111,12 @@ pub enum FlpError {
|
|||
/// An error happened during noising.
|
||||
#[error("differential privacy error: {0}")]
|
||||
DifferentialPrivacy(#[from] crate::dp::DpError),
|
||||
|
||||
/// Unit test error.
|
||||
#[cfg(test)]
|
||||
#[error("test failed: {0}")]
|
||||
Test(String),
|
||||
}
|
||||
|
||||
/// A type. Implementations of this trait specify how a particular kind of measurement is encoded
|
||||
/// as a vector of field elements and how validity of the encoded measurement is determined.
|
||||
/// Validity is determined via an arithmetic circuit evaluated over the encoded measurement.
|
||||
pub trait Type: Sized + Eq + Clone + Debug {
|
||||
/// The Prio3 VDAF identifier corresponding to this type.
|
||||
const ID: u32;
|
||||
|
||||
/// The type of raw measurement to be encoded.
|
||||
type Measurement: Clone + Debug;
|
||||
|
||||
|
@ -178,7 +171,7 @@ pub trait Type: Sized + Eq + Clone + Debug {
|
|||
/// use prio::field::{random_vector, FieldElement, Field64};
|
||||
///
|
||||
/// let count = Count::new();
|
||||
/// let input: Vec<Field64> = count.encode_measurement(&1).unwrap();
|
||||
/// let input: Vec<Field64> = count.encode_measurement(&true).unwrap();
|
||||
/// let joint_rand = random_vector(count.joint_rand_len()).unwrap();
|
||||
/// let v = count.valid(&mut count.gadget(), &input, &joint_rand, 1).unwrap();
|
||||
/// assert_eq!(v, Field64::zero());
|
||||
|
@ -552,6 +545,7 @@ pub trait Type: Sized + Eq + Clone + Debug {
|
|||
|
||||
/// A type which supports adding noise to aggregate shares for Server Differential Privacy.
|
||||
#[cfg(feature = "experimental")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
|
||||
pub trait TypeWithNoise<S>: Type
|
||||
where
|
||||
S: DifferentialPrivacyStrategy,
|
||||
|
@ -754,6 +748,227 @@ pub(crate) fn gadget_poly_len(gadget_degree: usize, wire_poly_len: usize) -> usi
|
|||
gadget_degree * (wire_poly_len - 1) + 1
|
||||
}
|
||||
|
||||
/// Utilities for testing FLPs.
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub mod test_utils {
|
||||
use super::*;
|
||||
use crate::field::{random_vector, FieldElement, FieldElementWithInteger};
|
||||
|
||||
/// Various tests for an FLP.
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub struct FlpTest<'a, T: Type> {
|
||||
/// The FLP.
|
||||
pub flp: &'a T,
|
||||
|
||||
/// Optional test name.
|
||||
pub name: Option<&'a str>,
|
||||
|
||||
/// The input to use for the tests.
|
||||
pub input: &'a [T::Field],
|
||||
|
||||
/// If set, the expected result of truncating the input.
|
||||
pub expected_output: Option<&'a [T::Field]>,
|
||||
|
||||
/// Whether the input is expected to be valid.
|
||||
pub expect_valid: bool,
|
||||
}
|
||||
|
||||
impl<T: Type> FlpTest<'_, T> {
|
||||
/// Construct a test and run it. Expect the input to be valid and compare the truncated
|
||||
/// output to the provided value.
|
||||
pub fn expect_valid<const SHARES: usize>(
|
||||
flp: &T,
|
||||
input: &[T::Field],
|
||||
expected_output: &[T::Field],
|
||||
) {
|
||||
FlpTest {
|
||||
flp,
|
||||
name: None,
|
||||
input,
|
||||
expected_output: Some(expected_output),
|
||||
expect_valid: true,
|
||||
}
|
||||
.run::<SHARES>()
|
||||
}
|
||||
|
||||
/// Construct a test and run it. Expect the input to be invalid.
|
||||
pub fn expect_invalid<const SHARES: usize>(flp: &T, input: &[T::Field]) {
|
||||
FlpTest {
|
||||
flp,
|
||||
name: None,
|
||||
input,
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
}
|
||||
.run::<SHARES>()
|
||||
}
|
||||
|
||||
/// Construct a test and run it. Expect the input to be valid.
|
||||
pub fn expect_valid_no_output<const SHARES: usize>(flp: &T, input: &[T::Field]) {
|
||||
FlpTest {
|
||||
flp,
|
||||
name: None,
|
||||
input,
|
||||
expect_valid: true,
|
||||
expected_output: None,
|
||||
}
|
||||
.run::<SHARES>()
|
||||
}
|
||||
|
||||
/// Run the tests.
|
||||
pub fn run<const SHARES: usize>(&self) {
|
||||
let name = self.name.unwrap_or("unnamed test");
|
||||
|
||||
assert_eq!(
|
||||
self.input.len(),
|
||||
self.flp.input_len(),
|
||||
"{name}: unexpected input length"
|
||||
);
|
||||
|
||||
let mut gadgets = self.flp.gadget();
|
||||
let joint_rand = random_vector(self.flp.joint_rand_len()).unwrap();
|
||||
let prove_rand = random_vector(self.flp.prove_rand_len()).unwrap();
|
||||
let query_rand = random_vector(self.flp.query_rand_len()).unwrap();
|
||||
assert_eq!(
|
||||
self.flp.query_rand_len(),
|
||||
gadgets.len(),
|
||||
"{name}: unexpected number of gadgets"
|
||||
);
|
||||
assert_eq!(
|
||||
self.flp.joint_rand_len(),
|
||||
joint_rand.len(),
|
||||
"{name}: unexpected joint rand length"
|
||||
);
|
||||
assert_eq!(
|
||||
self.flp.prove_rand_len(),
|
||||
prove_rand.len(),
|
||||
"{name}: unexpected prove rand length",
|
||||
);
|
||||
assert_eq!(
|
||||
self.flp.query_rand_len(),
|
||||
query_rand.len(),
|
||||
"{name}: unexpected query rand length",
|
||||
);
|
||||
|
||||
// Run the validity circuit.
|
||||
let v = self
|
||||
.flp
|
||||
.valid(&mut gadgets, self.input, &joint_rand, 1)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
v == T::Field::zero(),
|
||||
self.expect_valid,
|
||||
"{name}: unexpected output of valid() returned {v}",
|
||||
);
|
||||
|
||||
// Generate the proof.
|
||||
let proof = self
|
||||
.flp
|
||||
.prove(self.input, &prove_rand, &joint_rand)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
proof.len(),
|
||||
self.flp.proof_len(),
|
||||
"{name}: unexpected proof length"
|
||||
);
|
||||
|
||||
// Query the proof.
|
||||
let verifier = self
|
||||
.flp
|
||||
.query(self.input, &proof, &query_rand, &joint_rand, 1)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verifier.len(),
|
||||
self.flp.verifier_len(),
|
||||
"{name}: unexpected verifier length"
|
||||
);
|
||||
|
||||
// Decide if the input is valid.
|
||||
let res = self.flp.decide(&verifier).unwrap();
|
||||
assert_eq!(res, self.expect_valid, "{name}: unexpected decision");
|
||||
|
||||
// Run distributed FLP.
|
||||
let input_shares = split_vector::<_, SHARES>(self.input);
|
||||
let proof_shares = split_vector::<_, SHARES>(&proof);
|
||||
let verifier: Vec<T::Field> = (0..SHARES)
|
||||
.map(|i| {
|
||||
self.flp
|
||||
.query(
|
||||
&input_shares[i],
|
||||
&proof_shares[i],
|
||||
&query_rand,
|
||||
&joint_rand,
|
||||
SHARES,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.reduce(|mut left, right| {
|
||||
for (x, y) in left.iter_mut().zip(right.iter()) {
|
||||
*x += *y;
|
||||
}
|
||||
left
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let res = self.flp.decide(&verifier).unwrap();
|
||||
assert_eq!(
|
||||
res, self.expect_valid,
|
||||
"{name}: unexpected distributed decision"
|
||||
);
|
||||
|
||||
// Try verifying various proof mutants.
|
||||
for i in 0..std::cmp::min(proof.len(), 10) {
|
||||
let mut mutated_proof = proof.clone();
|
||||
mutated_proof[i] *= T::Field::from(
|
||||
<T::Field as FieldElementWithInteger>::Integer::try_from(23).unwrap(),
|
||||
);
|
||||
let verifier = self
|
||||
.flp
|
||||
.query(self.input, &mutated_proof, &query_rand, &joint_rand, 1)
|
||||
.unwrap();
|
||||
assert!(
|
||||
!self.flp.decide(&verifier).unwrap(),
|
||||
"{name}: proof mutant {} deemed valid",
|
||||
i
|
||||
);
|
||||
}
|
||||
|
||||
// Try truncating the input.
|
||||
if let Some(ref expected_output) = self.expected_output {
|
||||
let output = self.flp.truncate(self.input.to_vec()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
output.len(),
|
||||
self.flp.output_len(),
|
||||
"{name}: unexpected output length of truncate()"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
&output, expected_output,
|
||||
"{name}: unexpected output of truncate()"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn split_vector<F: FieldElement, const SHARES: usize>(inp: &[F]) -> [Vec<F>; SHARES] {
|
||||
let mut outp = Vec::with_capacity(SHARES);
|
||||
outp.push(inp.to_vec());
|
||||
|
||||
for _ in 1..SHARES {
|
||||
let share: Vec<F> =
|
||||
random_vector(inp.len()).expect("failed to generate a random vector");
|
||||
for (x, y) in outp[0].iter_mut().zip(&share) {
|
||||
*x -= *y;
|
||||
}
|
||||
outp.push(share);
|
||||
}
|
||||
|
||||
outp.try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -825,7 +1040,6 @@ mod tests {
|
|||
}
|
||||
|
||||
impl<F: FftFriendlyFieldElement> Type for TestType<F> {
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
type Measurement = F::Integer;
|
||||
type AggregateResult = F::Integer;
|
||||
type Field = F;
|
||||
|
@ -960,7 +1174,6 @@ mod tests {
|
|||
}
|
||||
|
||||
impl<F: FftFriendlyFieldElement> Type for Issue254Type<F> {
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
type Measurement = F::Integer;
|
||||
type AggregateResult = F::Integer;
|
||||
type Field = F;
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::polynomial::poly_range_check;
|
|||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::marker::PhantomData;
|
||||
use subtle::Choice;
|
||||
/// The counter data type. Each measurement is `0` or `1` and the aggregate result is the sum of the measurements (i.e., the total number of `1s`).
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Count<F> {
|
||||
|
@ -37,18 +38,16 @@ impl<F: FftFriendlyFieldElement> Default for Count<F> {
|
|||
}
|
||||
|
||||
impl<F: FftFriendlyFieldElement> Type for Count<F> {
|
||||
const ID: u32 = 0x00000000;
|
||||
type Measurement = F::Integer;
|
||||
type Measurement = bool;
|
||||
type AggregateResult = F::Integer;
|
||||
type Field = F;
|
||||
|
||||
fn encode_measurement(&self, value: &F::Integer) -> Result<Vec<F>, FlpError> {
|
||||
let max = F::valid_integer_try_from(1)?;
|
||||
if *value > max {
|
||||
return Err(FlpError::Encode("Count value must be 0 or 1".to_string()));
|
||||
}
|
||||
|
||||
Ok(vec![F::from(*value)])
|
||||
fn encode_measurement(&self, value: &bool) -> Result<Vec<F>, FlpError> {
|
||||
Ok(vec![F::conditional_select(
|
||||
&F::zero(),
|
||||
&F::one(),
|
||||
Choice::from(u8::from(*value)),
|
||||
)])
|
||||
}
|
||||
|
||||
fn decode_result(&self, data: &[F], _num_measurements: usize) -> Result<F::Integer, FlpError> {
|
||||
|
@ -140,13 +139,12 @@ impl<F: FftFriendlyFieldElement> Sum<F> {
|
|||
}
|
||||
|
||||
impl<F: FftFriendlyFieldElement> Type for Sum<F> {
|
||||
const ID: u32 = 0x00000001;
|
||||
type Measurement = F::Integer;
|
||||
type AggregateResult = F::Integer;
|
||||
type Field = F;
|
||||
|
||||
fn encode_measurement(&self, summand: &F::Integer) -> Result<Vec<F>, FlpError> {
|
||||
let v = F::encode_into_bitvector_representation(summand, self.bits)?;
|
||||
let v = F::encode_as_bitvector(*summand, self.bits)?.collect();
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
|
@ -174,7 +172,7 @@ impl<F: FftFriendlyFieldElement> Type for Sum<F> {
|
|||
|
||||
fn truncate(&self, input: Vec<F>) -> Result<Vec<F>, FlpError> {
|
||||
self.truncate_call_check(&input)?;
|
||||
let res = F::decode_from_bitvector_representation(&input)?;
|
||||
let res = F::decode_bitvector(&input)?;
|
||||
Ok(vec![res])
|
||||
}
|
||||
|
||||
|
@ -239,13 +237,12 @@ impl<F: FftFriendlyFieldElement> Average<F> {
|
|||
}
|
||||
|
||||
impl<F: FftFriendlyFieldElement> Type for Average<F> {
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
type Measurement = F::Integer;
|
||||
type AggregateResult = f64;
|
||||
type Field = F;
|
||||
|
||||
fn encode_measurement(&self, summand: &F::Integer) -> Result<Vec<F>, FlpError> {
|
||||
let v = F::encode_into_bitvector_representation(summand, self.bits)?;
|
||||
let v = F::encode_as_bitvector(*summand, self.bits)?.collect();
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
|
@ -279,7 +276,7 @@ impl<F: FftFriendlyFieldElement> Type for Average<F> {
|
|||
|
||||
fn truncate(&self, input: Vec<F>) -> Result<Vec<F>, FlpError> {
|
||||
self.truncate_call_check(&input)?;
|
||||
let res = F::decode_from_bitvector_representation(&input)?;
|
||||
let res = F::decode_bitvector(&input)?;
|
||||
Ok(vec![res])
|
||||
}
|
||||
|
||||
|
@ -380,7 +377,6 @@ where
|
|||
F: FftFriendlyFieldElement,
|
||||
S: ParallelSumGadget<F, Mul<F>> + Eq + 'static,
|
||||
{
|
||||
const ID: u32 = 0x00000003;
|
||||
type Measurement = usize;
|
||||
type AggregateResult = Vec<F::Integer>;
|
||||
type Field = F;
|
||||
|
@ -574,7 +570,6 @@ where
|
|||
F: FftFriendlyFieldElement,
|
||||
S: ParallelSumGadget<F, Mul<F>> + Eq + 'static,
|
||||
{
|
||||
const ID: u32 = 0x00000002;
|
||||
type Measurement = Vec<F::Integer>;
|
||||
type AggregateResult = Vec<F::Integer>;
|
||||
type Field = F;
|
||||
|
@ -588,18 +583,15 @@ where
|
|||
)));
|
||||
}
|
||||
|
||||
let mut flattened = vec![F::zero(); self.flattened_len];
|
||||
for (summand, chunk) in measurement
|
||||
.iter()
|
||||
.zip(flattened.chunks_exact_mut(self.bits))
|
||||
{
|
||||
let mut flattened = Vec::with_capacity(self.flattened_len);
|
||||
for summand in measurement.iter() {
|
||||
if summand > &self.max {
|
||||
return Err(FlpError::Encode(format!(
|
||||
"summand exceeds maximum of 2^{}-1",
|
||||
self.bits
|
||||
)));
|
||||
}
|
||||
F::fill_with_bitvector_representation(summand, chunk)?;
|
||||
flattened.extend(F::encode_as_bitvector(*summand, self.bits)?);
|
||||
}
|
||||
|
||||
Ok(flattened)
|
||||
|
@ -642,7 +634,7 @@ where
|
|||
self.truncate_call_check(&input)?;
|
||||
let mut unflattened = Vec::with_capacity(self.len);
|
||||
for chunk in input.chunks(self.bits) {
|
||||
unflattened.push(F::decode_from_bitvector_representation(chunk)?);
|
||||
unflattened.push(F::decode_bitvector(chunk)?);
|
||||
}
|
||||
Ok(unflattened)
|
||||
}
|
||||
|
@ -783,7 +775,7 @@ mod tests {
|
|||
use crate::flp::gadgets::ParallelSum;
|
||||
#[cfg(feature = "multithreaded")]
|
||||
use crate::flp::gadgets::ParallelSumMultithreaded;
|
||||
use crate::flp::types::test_utils::{flp_validity_test, ValidityTestCase};
|
||||
use crate::flp::test_utils::FlpTest;
|
||||
use std::cmp;
|
||||
|
||||
#[test]
|
||||
|
@ -797,7 +789,7 @@ mod tests {
|
|||
count
|
||||
.decode_result(
|
||||
&count
|
||||
.truncate(count.encode_measurement(&1).unwrap())
|
||||
.truncate(count.encode_measurement(&true).unwrap())
|
||||
.unwrap(),
|
||||
1
|
||||
)
|
||||
|
@ -806,39 +798,11 @@ mod tests {
|
|||
);
|
||||
|
||||
// Test FLP on valid input.
|
||||
flp_validity_test(
|
||||
&count,
|
||||
&count.encode_measurement(&1).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![one]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&count,
|
||||
&count.encode_measurement(&0).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![zero]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_valid::<3>(&count, &count.encode_measurement(&true).unwrap(), &[one]);
|
||||
FlpTest::expect_valid::<3>(&count, &count.encode_measurement(&false).unwrap(), &[zero]);
|
||||
|
||||
// Test FLP on invalid input.
|
||||
flp_validity_test(
|
||||
&count,
|
||||
&[TestField::from(1337)],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_invalid::<3>(&count, &[TestField::from(1337)]);
|
||||
|
||||
// Try running the validity circuit on an input that's too short.
|
||||
count.valid(&mut count.gadget(), &[], &[], 1).unwrap_err();
|
||||
|
@ -865,72 +829,22 @@ mod tests {
|
|||
);
|
||||
|
||||
// Test FLP on valid input.
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&sum,
|
||||
&sum.encode_measurement(&1337).unwrap(),
|
||||
&ValidityTestCase {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![TestField::from(1337)]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&Sum::new(0).unwrap(),
|
||||
&[],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![zero]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&Sum::new(2).unwrap(),
|
||||
&[one, zero],
|
||||
&ValidityTestCase {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![one]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&[TestField::from(1337)],
|
||||
);
|
||||
FlpTest::expect_valid::<3>(&Sum::new(0).unwrap(), &[], &[zero]);
|
||||
FlpTest::expect_valid::<3>(&Sum::new(2).unwrap(), &[one, zero], &[one]);
|
||||
FlpTest::expect_valid::<3>(
|
||||
&Sum::new(9).unwrap(),
|
||||
&[one, zero, one, one, zero, one, one, one, zero],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![TestField::from(237)]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&[TestField::from(237)],
|
||||
);
|
||||
|
||||
// Test FLP on invalid input.
|
||||
flp_validity_test(
|
||||
&Sum::new(3).unwrap(),
|
||||
&[one, nine, zero],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&Sum::new(5).unwrap(),
|
||||
&[zero, zero, zero, zero, nine],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_invalid::<3>(&Sum::new(3).unwrap(), &[one, nine, zero]);
|
||||
FlpTest::expect_invalid::<3>(&Sum::new(5).unwrap(), &[zero, zero, zero, zero, nine]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1000,83 +914,29 @@ mod tests {
|
|||
);
|
||||
|
||||
// Test valid inputs.
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&hist,
|
||||
&hist.encode_measurement(&0).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![one, zero, zero]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&[one, zero, zero],
|
||||
);
|
||||
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&hist,
|
||||
&hist.encode_measurement(&1).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![zero, one, zero]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&[zero, one, zero],
|
||||
);
|
||||
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&hist,
|
||||
&hist.encode_measurement(&2).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![zero, zero, one]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&[zero, zero, one],
|
||||
);
|
||||
|
||||
// Test invalid inputs.
|
||||
flp_validity_test(
|
||||
&hist,
|
||||
&[zero, zero, nine],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&hist,
|
||||
&[zero, one, one],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&hist,
|
||||
&[one, one, one],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
flp_validity_test(
|
||||
&hist,
|
||||
&[zero, zero, zero],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_invalid::<3>(&hist, &[zero, zero, nine]);
|
||||
FlpTest::expect_invalid::<3>(&hist, &[zero, one, one]);
|
||||
FlpTest::expect_invalid::<3>(&hist, &[one, one, one]);
|
||||
FlpTest::expect_invalid::<3>(&hist, &[zero, zero, zero]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1104,72 +964,38 @@ mod tests {
|
|||
for len in 1..10 {
|
||||
let chunk_length = cmp::max((len as f64).sqrt() as usize, 1);
|
||||
let sum_vec = f(1, len, chunk_length).unwrap();
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid_no_output::<3>(
|
||||
&sum_vec,
|
||||
&sum_vec.encode_measurement(&vec![1; len]).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![one; len]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
}
|
||||
|
||||
let len = 100;
|
||||
let sum_vec = f(1, len, 10).unwrap();
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&sum_vec,
|
||||
&sum_vec.encode_measurement(&vec![1; len]).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![one; len]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&vec![one; len],
|
||||
);
|
||||
|
||||
let len = 23;
|
||||
let sum_vec = f(4, len, 4).unwrap();
|
||||
flp_validity_test(
|
||||
FlpTest::expect_valid::<3>(
|
||||
&sum_vec,
|
||||
&sum_vec.encode_measurement(&vec![9; len]).unwrap(),
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: true,
|
||||
expected_output: Some(vec![nine; len]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
&vec![nine; len],
|
||||
);
|
||||
|
||||
// Test on invalid inputs.
|
||||
for len in 1..10 {
|
||||
let chunk_length = cmp::max((len as f64).sqrt() as usize, 1);
|
||||
let sum_vec = f(1, len, chunk_length).unwrap();
|
||||
flp_validity_test(
|
||||
&sum_vec,
|
||||
&vec![nine; len],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_invalid::<3>(&sum_vec, &vec![nine; len]);
|
||||
}
|
||||
|
||||
let len = 23;
|
||||
let sum_vec = f(2, len, 4).unwrap();
|
||||
flp_validity_test(
|
||||
&sum_vec,
|
||||
&vec![nine; 2 * len],
|
||||
&ValidityTestCase::<TestField> {
|
||||
expect_valid: false,
|
||||
expected_output: None,
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest::expect_invalid::<3>(&sum_vec, &vec![nine; 2 * len]);
|
||||
|
||||
// Round trip
|
||||
let want = vec![1; len];
|
||||
|
@ -1232,184 +1058,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_utils {
|
||||
use super::*;
|
||||
use crate::field::{random_vector, split_vector, FieldElement};
|
||||
|
||||
pub(crate) struct ValidityTestCase<F> {
|
||||
pub(crate) expect_valid: bool,
|
||||
pub(crate) expected_output: Option<Vec<F>>,
|
||||
// Number of shares to split input and proofs into in `flp_test`.
|
||||
pub(crate) num_shares: usize,
|
||||
}
|
||||
|
||||
pub(crate) fn flp_validity_test<T: Type>(
|
||||
typ: &T,
|
||||
input: &[T::Field],
|
||||
t: &ValidityTestCase<T::Field>,
|
||||
) -> Result<(), FlpError> {
|
||||
let mut gadgets = typ.gadget();
|
||||
|
||||
if input.len() != typ.input_len() {
|
||||
return Err(FlpError::Test(format!(
|
||||
"unexpected input length: got {}; want {}",
|
||||
input.len(),
|
||||
typ.input_len()
|
||||
)));
|
||||
}
|
||||
|
||||
if typ.query_rand_len() != gadgets.len() {
|
||||
return Err(FlpError::Test(format!(
|
||||
"query rand length: got {}; want {}",
|
||||
typ.query_rand_len(),
|
||||
gadgets.len()
|
||||
)));
|
||||
}
|
||||
|
||||
let joint_rand = random_vector(typ.joint_rand_len()).unwrap();
|
||||
let prove_rand = random_vector(typ.prove_rand_len()).unwrap();
|
||||
let query_rand = random_vector(typ.query_rand_len()).unwrap();
|
||||
|
||||
// Run the validity circuit.
|
||||
let v = typ.valid(&mut gadgets, input, &joint_rand, 1)?;
|
||||
if v != T::Field::zero() && t.expect_valid {
|
||||
return Err(FlpError::Test(format!(
|
||||
"expected valid input: valid() returned {v}"
|
||||
)));
|
||||
}
|
||||
if v == T::Field::zero() && !t.expect_valid {
|
||||
return Err(FlpError::Test(format!(
|
||||
"expected invalid input: valid() returned {v}"
|
||||
)));
|
||||
}
|
||||
|
||||
// Generate the proof.
|
||||
let proof = typ.prove(input, &prove_rand, &joint_rand)?;
|
||||
if proof.len() != typ.proof_len() {
|
||||
return Err(FlpError::Test(format!(
|
||||
"unexpected proof length: got {}; want {}",
|
||||
proof.len(),
|
||||
typ.proof_len()
|
||||
)));
|
||||
}
|
||||
|
||||
// Query the proof.
|
||||
let verifier = typ.query(input, &proof, &query_rand, &joint_rand, 1)?;
|
||||
if verifier.len() != typ.verifier_len() {
|
||||
return Err(FlpError::Test(format!(
|
||||
"unexpected verifier length: got {}; want {}",
|
||||
verifier.len(),
|
||||
typ.verifier_len()
|
||||
)));
|
||||
}
|
||||
|
||||
// Decide if the input is valid.
|
||||
let res = typ.decide(&verifier)?;
|
||||
if res != t.expect_valid {
|
||||
return Err(FlpError::Test(format!(
|
||||
"decision is {}; want {}",
|
||||
res, t.expect_valid,
|
||||
)));
|
||||
}
|
||||
|
||||
// Run distributed FLP.
|
||||
let input_shares: Vec<Vec<T::Field>> = split_vector(input, t.num_shares)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let proof_shares: Vec<Vec<T::Field>> = split_vector(&proof, t.num_shares)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let verifier: Vec<T::Field> = (0..t.num_shares)
|
||||
.map(|i| {
|
||||
typ.query(
|
||||
&input_shares[i],
|
||||
&proof_shares[i],
|
||||
&query_rand,
|
||||
&joint_rand,
|
||||
t.num_shares,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.reduce(|mut left, right| {
|
||||
for (x, y) in left.iter_mut().zip(right.iter()) {
|
||||
*x += *y;
|
||||
}
|
||||
left
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let res = typ.decide(&verifier)?;
|
||||
if res != t.expect_valid {
|
||||
return Err(FlpError::Test(format!(
|
||||
"distributed decision is {}; want {}",
|
||||
res, t.expect_valid,
|
||||
)));
|
||||
}
|
||||
|
||||
// Try verifying various proof mutants.
|
||||
for i in 0..proof.len() {
|
||||
let mut mutated_proof = proof.clone();
|
||||
mutated_proof[i] += T::Field::one();
|
||||
let verifier = typ.query(input, &mutated_proof, &query_rand, &joint_rand, 1)?;
|
||||
if typ.decide(&verifier)? {
|
||||
return Err(FlpError::Test(format!(
|
||||
"decision for proof mutant {} is {}; want {}",
|
||||
i, true, false,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
// Try verifying a proof that is too short.
|
||||
let mut mutated_proof = proof.clone();
|
||||
mutated_proof.truncate(gadgets[0].arity() - 1);
|
||||
if typ
|
||||
.query(input, &mutated_proof, &query_rand, &joint_rand, 1)
|
||||
.is_ok()
|
||||
{
|
||||
return Err(FlpError::Test(
|
||||
"query on short proof succeeded; want failure".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// Try verifying a proof that is too long.
|
||||
let mut mutated_proof = proof;
|
||||
mutated_proof.extend_from_slice(&[T::Field::one(); 17]);
|
||||
if typ
|
||||
.query(input, &mutated_proof, &query_rand, &joint_rand, 1)
|
||||
.is_ok()
|
||||
{
|
||||
return Err(FlpError::Test(
|
||||
"query on long proof succeeded; want failure".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(ref want) = t.expected_output {
|
||||
let got = typ.truncate(input.to_vec())?;
|
||||
|
||||
if got.len() != typ.output_len() {
|
||||
return Err(FlpError::Test(format!(
|
||||
"unexpected output length: got {}; want {}",
|
||||
got.len(),
|
||||
typ.output_len()
|
||||
)));
|
||||
}
|
||||
|
||||
if &got != want {
|
||||
return Err(FlpError::Test(format!(
|
||||
"unexpected output: got {got:?}; want {want:?}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
|
||||
pub mod fixedpoint_l2;
|
||||
|
|
|
@ -172,15 +172,17 @@
|
|||
pub mod compatible_float;
|
||||
|
||||
use crate::dp::{distributions::ZCdpDiscreteGaussian, DifferentialPrivacyStrategy, DpError};
|
||||
use crate::field::{Field128, FieldElement, FieldElementWithInteger, FieldElementWithIntegerExt};
|
||||
use crate::field::{
|
||||
Field128, FieldElement, FieldElementWithInteger, FieldElementWithIntegerExt, Integer,
|
||||
};
|
||||
use crate::flp::gadgets::{Mul, ParallelSumGadget, PolyEval};
|
||||
use crate::flp::types::fixedpoint_l2::compatible_float::CompatibleFloat;
|
||||
use crate::flp::types::parallel_sum_range_checks;
|
||||
use crate::flp::{FlpError, Gadget, Type, TypeWithNoise};
|
||||
use crate::vdaf::xof::SeedStreamSha3;
|
||||
use crate::vdaf::xof::SeedStreamTurboShake128;
|
||||
use fixed::traits::Fixed;
|
||||
use num_bigint::{BigInt, BigUint, TryFromBigIntError};
|
||||
use num_integer::Integer;
|
||||
use num_integer::Integer as _;
|
||||
use num_rational::Ratio;
|
||||
use rand::{distributions::Distribution, Rng};
|
||||
use rand_core::SeedableRng;
|
||||
|
@ -250,7 +252,7 @@ where
|
|||
/// fixed point vector with `entries` entries.
|
||||
pub fn new(entries: usize) -> Result<Self, FlpError> {
|
||||
// (0) initialize constants
|
||||
let fi_one = u128::from(Field128::one());
|
||||
let fi_one = <Field128 as FieldElementWithInteger>::Integer::one();
|
||||
|
||||
// (I) Check that the fixed type is compatible.
|
||||
//
|
||||
|
@ -400,7 +402,6 @@ where
|
|||
SPoly: ParallelSumGadget<Field128, PolyEval<Field128>> + Eq + Clone + 'static,
|
||||
SMul: ParallelSumGadget<Field128, Mul<Field128>> + Eq + Clone + 'static,
|
||||
{
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
type Measurement = Vec<T>;
|
||||
type AggregateResult = Vec<f64>;
|
||||
type Field = Field128;
|
||||
|
@ -419,12 +420,9 @@ where
|
|||
// Encode the integer entries bitwise, and write them into the `encoded`
|
||||
// vector.
|
||||
let mut encoded: Vec<Field128> =
|
||||
vec![Field128::zero(); self.bits_per_entry * self.entries + self.bits_for_norm];
|
||||
for (l, entry) in integer_entries.clone().enumerate() {
|
||||
Field128::fill_with_bitvector_representation(
|
||||
&entry,
|
||||
&mut encoded[l * self.bits_per_entry..(l + 1) * self.bits_per_entry],
|
||||
)?;
|
||||
Vec::with_capacity(self.bits_per_entry * self.entries + self.bits_for_norm);
|
||||
for entry in integer_entries.clone() {
|
||||
encoded.extend(Field128::encode_as_bitvector(entry, self.bits_per_entry)?);
|
||||
}
|
||||
|
||||
// (II) Vector norm.
|
||||
|
@ -434,10 +432,7 @@ where
|
|||
let norm_int = u128::from(norm);
|
||||
|
||||
// Write the norm into the `entries` vector.
|
||||
Field128::fill_with_bitvector_representation(
|
||||
&norm_int,
|
||||
&mut encoded[self.range_norm_begin..self.range_norm_end],
|
||||
)?;
|
||||
encoded.extend(Field128::encode_as_bitvector(norm_int, self.bits_for_norm)?);
|
||||
|
||||
Ok(encoded)
|
||||
}
|
||||
|
@ -535,7 +530,7 @@ where
|
|||
// decode the bit-encoded entries into elements in the range [0,2^n):
|
||||
let decoded_entries: Result<Vec<_>, _> = input[0..self.entries * self.bits_per_entry]
|
||||
.chunks(self.bits_per_entry)
|
||||
.map(Field128::decode_from_bitvector_representation)
|
||||
.map(Field128::decode_bitvector)
|
||||
.collect();
|
||||
|
||||
// run parallel sum gadget on the decoded entries
|
||||
|
@ -544,7 +539,7 @@ where
|
|||
|
||||
// Chunks which are too short need to be extended with a share of the
|
||||
// encoded zero value, that is: 1/num_shares * (2^(n-1))
|
||||
let fi_one = u128::from(Field128::one());
|
||||
let fi_one = <Field128 as FieldElementWithInteger>::Integer::one();
|
||||
let zero_enc = Field128::from(fi_one << (self.bits_per_entry - 1));
|
||||
let zero_enc_share = zero_enc * num_shares_inverse;
|
||||
|
||||
|
@ -567,7 +562,7 @@ where
|
|||
// The submitted norm is also decoded from its bit-encoding, and
|
||||
// compared with the computed norm.
|
||||
let submitted_norm_enc = &input[self.range_norm_begin..self.range_norm_end];
|
||||
let submitted_norm = Field128::decode_from_bitvector_representation(submitted_norm_enc)?;
|
||||
let submitted_norm = Field128::decode_bitvector(submitted_norm_enc)?;
|
||||
|
||||
let norm_check = computed_norm - submitted_norm;
|
||||
|
||||
|
@ -586,7 +581,7 @@ where
|
|||
let start = i_entry * self.bits_per_entry;
|
||||
let end = (i_entry + 1) * self.bits_per_entry;
|
||||
|
||||
let decoded = Field128::decode_from_bitvector_representation(&input[start..end])?;
|
||||
let decoded = Field128::decode_bitvector(&input[start..end])?;
|
||||
decoded_vector.push(decoded);
|
||||
}
|
||||
Ok(decoded_vector)
|
||||
|
@ -644,7 +639,11 @@ where
|
|||
agg_result: &mut [Self::Field],
|
||||
_num_measurements: usize,
|
||||
) -> Result<(), FlpError> {
|
||||
self.add_noise(dp_strategy, agg_result, &mut SeedStreamSha3::from_entropy())
|
||||
self.add_noise(
|
||||
dp_strategy,
|
||||
agg_result,
|
||||
&mut SeedStreamTurboShake128::from_entropy(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,8 +685,8 @@ mod tests {
|
|||
use crate::dp::{Rational, ZCdpBudget};
|
||||
use crate::field::{random_vector, Field128, FieldElement};
|
||||
use crate::flp::gadgets::ParallelSum;
|
||||
use crate::flp::types::test_utils::{flp_validity_test, ValidityTestCase};
|
||||
use crate::vdaf::xof::SeedStreamSha3;
|
||||
use crate::flp::test_utils::FlpTest;
|
||||
use crate::vdaf::xof::SeedStreamTurboShake128;
|
||||
use fixed::types::extra::{U127, U14, U63};
|
||||
use fixed::{FixedI128, FixedI16, FixedI64};
|
||||
use fixed_macro::fixed;
|
||||
|
@ -768,15 +767,23 @@ mod tests {
|
|||
let strategy = ZCdpDiscreteGaussian::from_budget(ZCdpBudget::new(
|
||||
Rational::from_unsigned(100u8, 3u8).unwrap(),
|
||||
));
|
||||
vsum.add_noise(&strategy, &mut v, &mut SeedStreamSha3::from_seed([0u8; 16]))
|
||||
.unwrap();
|
||||
vsum.add_noise(
|
||||
&strategy,
|
||||
&mut v,
|
||||
&mut SeedStreamTurboShake128::from_seed([0u8; 16]),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
vsum.decode_result(&v, 1).unwrap(),
|
||||
match n {
|
||||
// sensitivity depends on encoding so the noise differs
|
||||
16 => vec![0.150604248046875, 0.139373779296875, -0.03759765625],
|
||||
32 => vec![0.3051439793780446, 0.1226568529382348, 0.08595499861985445],
|
||||
64 => vec![0.2896077990915178, 0.16115188007715098, 0.0788390114728425],
|
||||
16 => vec![0.288970947265625, 0.168853759765625, 0.085662841796875],
|
||||
32 => vec![0.257810294162482, 0.10634658299386501, 0.10149003705009818],
|
||||
64 => vec![
|
||||
0.37697368351762867,
|
||||
-0.02388947667663828,
|
||||
0.19813152630930916
|
||||
],
|
||||
_ => panic!("unsupported bitsize"),
|
||||
}
|
||||
);
|
||||
|
@ -785,52 +792,46 @@ mod tests {
|
|||
let mut input: Vec<Field128> = vsum.encode_measurement(&fp_vec).unwrap();
|
||||
assert_eq!(input[0], Field128::zero());
|
||||
input[0] = one; // it was zero
|
||||
flp_validity_test(
|
||||
&vsum,
|
||||
&input,
|
||||
&ValidityTestCase::<Field128> {
|
||||
expect_valid: false,
|
||||
expected_output: Some(vec![
|
||||
Field128::from(enc_vec[0] + 1), // = enc(0.25) + 2^0
|
||||
Field128::from(enc_vec[1]),
|
||||
Field128::from(enc_vec[2]),
|
||||
]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest {
|
||||
name: None,
|
||||
flp: &vsum,
|
||||
input: &input,
|
||||
expected_output: Some(&[
|
||||
Field128::from(enc_vec[0] + 1), // = enc(0.25) + 2^0
|
||||
Field128::from(enc_vec[1]),
|
||||
Field128::from(enc_vec[2]),
|
||||
]),
|
||||
expect_valid: false,
|
||||
}
|
||||
.run::<3>();
|
||||
|
||||
// encoding contains entries that are not zero or one
|
||||
let mut input2: Vec<Field128> = vsum.encode_measurement(&fp_vec).unwrap();
|
||||
input2[0] = one + one;
|
||||
flp_validity_test(
|
||||
&vsum,
|
||||
&input2,
|
||||
&ValidityTestCase::<Field128> {
|
||||
expect_valid: false,
|
||||
expected_output: Some(vec![
|
||||
Field128::from(enc_vec[0] + 2), // = enc(0.25) + 2*2^0
|
||||
Field128::from(enc_vec[1]),
|
||||
Field128::from(enc_vec[2]),
|
||||
]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest {
|
||||
name: None,
|
||||
flp: &vsum,
|
||||
input: &input2,
|
||||
expected_output: Some(&[
|
||||
Field128::from(enc_vec[0] + 2), // = enc(0.25) + 2*2^0
|
||||
Field128::from(enc_vec[1]),
|
||||
Field128::from(enc_vec[2]),
|
||||
]),
|
||||
expect_valid: false,
|
||||
}
|
||||
.run::<3>();
|
||||
|
||||
// norm is too big
|
||||
// 2^n - 1, the field element encoded by the all-1 vector
|
||||
let one_enc = Field128::from(((2_u128) << (n - 1)) - 1);
|
||||
flp_validity_test(
|
||||
&vsum,
|
||||
&vec![one; 3 * n + 2 * n - 2], // all vector entries and the norm are all-1-vectors
|
||||
&ValidityTestCase::<Field128> {
|
||||
expect_valid: false,
|
||||
expected_output: Some(vec![one_enc; 3]),
|
||||
num_shares: 3,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
FlpTest {
|
||||
name: None,
|
||||
flp: &vsum,
|
||||
input: &vec![one; 3 * n + 2 * n - 2], // all vector entries and the norm are all-1-vectors
|
||||
expected_output: Some(&[one_enc; 3]),
|
||||
expect_valid: false,
|
||||
}
|
||||
.run::<3>();
|
||||
|
||||
// invalid submission length, should be 3n + (2*n - 2) for a
|
||||
// 3-element n-bit vector. 3*n bits for 3 entries, (2*n-2) for norm.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! This module implements the incremental distributed point function (IDPF) described in
|
||||
//! [[draft-irtf-cfrg-vdaf-07]].
|
||||
//! [[draft-irtf-cfrg-vdaf-08]].
|
||||
//!
|
||||
//! [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
//! [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
|
||||
use crate::{
|
||||
codec::{CodecError, Decode, Encode, ParameterizedDecode},
|
||||
|
@ -24,12 +24,14 @@ use std::{
|
|||
collections::{HashMap, VecDeque},
|
||||
fmt::Debug,
|
||||
io::{Cursor, Read},
|
||||
iter::zip,
|
||||
ops::{Add, AddAssign, ControlFlow, Index, Sub},
|
||||
};
|
||||
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};
|
||||
|
||||
/// IDPF-related errors.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum IdpfError {
|
||||
/// Error from incompatible shares at different levels.
|
||||
#[error("tried to merge shares from incompatible levels")]
|
||||
|
@ -107,6 +109,11 @@ impl IdpfInput {
|
|||
index: self.index[..=level].to_owned().into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the bit at the specified level if the level is in bounds.
|
||||
pub fn get(&self, level: usize) -> Option<bool> {
|
||||
self.index.get(level).as_deref().copied()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BitVec<usize, Lsb0>> for IdpfInput {
|
||||
|
@ -146,7 +153,7 @@ pub trait IdpfValue:
|
|||
+ Sub<Output = Self>
|
||||
+ ConditionallyNegatable
|
||||
+ Encode
|
||||
+ Decode
|
||||
+ ParameterizedDecode<Self::ValueParameter>
|
||||
+ Sized
|
||||
{
|
||||
/// Any run-time parameters needed to produce a value.
|
||||
|
@ -239,11 +246,13 @@ fn extend(seed: &[u8; 16], xof_fixed_key: &XofFixedKeyAes128Key) -> ([[u8; 16];
|
|||
seed_stream.fill_bytes(&mut seeds[0]);
|
||||
seed_stream.fill_bytes(&mut seeds[1]);
|
||||
|
||||
let mut byte = [0u8];
|
||||
seed_stream.fill_bytes(&mut byte);
|
||||
let control_bits = [(byte[0] & 1).into(), ((byte[0] >> 1) & 1).into()];
|
||||
// "Steal" the control bits from the seeds.
|
||||
let control_bits_0 = seeds[0].as_ref()[0] & 1;
|
||||
let control_bits_1 = seeds[1].as_ref()[0] & 1;
|
||||
seeds[0].as_mut()[0] &= 0xfe;
|
||||
seeds[1].as_mut()[0] &= 0xfe;
|
||||
|
||||
(seeds, control_bits)
|
||||
(seeds, [control_bits_0.into(), control_bits_1.into()])
|
||||
}
|
||||
|
||||
fn convert<V>(
|
||||
|
@ -670,7 +679,7 @@ where
|
|||
VI: Encode,
|
||||
VL: Encode,
|
||||
{
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
// Control bits need to be written within each byte in LSB-to-MSB order, and assigned into
|
||||
// bytes in big-endian order. Thus, the first four levels will have their control bits
|
||||
// encoded in the last byte, and the last levels will have their control bits encoded in the
|
||||
|
@ -691,11 +700,11 @@ where
|
|||
bytes.append(&mut packed_control);
|
||||
|
||||
for correction_words in self.inner_correction_words.iter() {
|
||||
Seed(correction_words.seed).encode(bytes);
|
||||
correction_words.value.encode(bytes);
|
||||
Seed(correction_words.seed).encode(bytes)?;
|
||||
correction_words.value.encode(bytes)?;
|
||||
}
|
||||
Seed(self.leaf_correction_word.seed).encode(bytes);
|
||||
self.leaf_correction_word.value.encode(bytes);
|
||||
Seed(self.leaf_correction_word.seed).encode(bytes)?;
|
||||
self.leaf_correction_word.value.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -785,7 +794,7 @@ where
|
|||
|
||||
impl<V> Eq for IdpfCorrectionWord<V> where V: ConstantTimeEq {}
|
||||
|
||||
fn xor_seeds(left: &[u8; 16], right: &[u8; 16]) -> [u8; 16] {
|
||||
pub(crate) fn xor_seeds(left: &[u8; 16], right: &[u8; 16]) -> [u8; 16] {
|
||||
let mut seed = [0u8; 16];
|
||||
for (a, (b, c)) in left.iter().zip(right.iter().zip(seed.iter_mut())) {
|
||||
*c = a ^ b;
|
||||
|
@ -819,7 +828,7 @@ fn control_bit_to_seed_mask(control: Choice) -> [u8; 16] {
|
|||
|
||||
/// Take two seeds and a control bit, and return the first seed if the control bit is zero, or the
|
||||
/// XOR of the two seeds if the control bit is one. This does not branch on the control bit.
|
||||
fn conditional_xor_seeds(
|
||||
pub(crate) fn conditional_xor_seeds(
|
||||
normal_input: &[u8; 16],
|
||||
switched_input: &[u8; 16],
|
||||
control: Choice,
|
||||
|
@ -832,13 +841,18 @@ fn conditional_xor_seeds(
|
|||
|
||||
/// Returns one of two seeds, depending on the value of a selector bit. Does not branch on the
|
||||
/// selector input or make selector-dependent memory accesses.
|
||||
fn conditional_select_seed(select: Choice, seeds: &[[u8; 16]; 2]) -> [u8; 16] {
|
||||
pub(crate) fn conditional_select_seed(select: Choice, seeds: &[[u8; 16]; 2]) -> [u8; 16] {
|
||||
or_seeds(
|
||||
&and_seeds(&control_bit_to_seed_mask(!select), &seeds[0]),
|
||||
&and_seeds(&control_bit_to_seed_mask(select), &seeds[1]),
|
||||
)
|
||||
}
|
||||
|
||||
/// Interchange the contents of seeds if the choice is 1, otherwise seeds remain unchanged.
|
||||
pub(crate) fn conditional_swap_seed(lhs: &mut [u8; 16], rhs: &mut [u8; 16], choice: Choice) {
|
||||
zip(lhs, rhs).for_each(|(a, b)| u8::conditional_swap(a, b, choice));
|
||||
}
|
||||
|
||||
/// An interface that provides memoization of IDPF computations.
|
||||
///
|
||||
/// Each instance of a type implementing `IdpfCache` should only be used with one IDPF key and
|
||||
|
@ -947,11 +961,91 @@ impl IdpfCache for RingBufferCache {
|
|||
}
|
||||
}
|
||||
|
||||
/// Utilities for testing IDPFs.
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub mod test_utils {
|
||||
use super::*;
|
||||
|
||||
use rand::prelude::*;
|
||||
use zipf::ZipfDistribution;
|
||||
|
||||
/// Generate a set of IDPF inputs with the given bit length `bits`. They are sampled according
|
||||
/// to the Zipf distribution with parameters `zipf_support` and `zipf_exponent`. Return the
|
||||
/// measurements, along with the prefixes traversed during the heavy hitters computation for
|
||||
/// the given threshold.
|
||||
///
|
||||
/// The prefix tree consists of a sequence of candidate prefixes for each level. For a given level,
|
||||
/// the candidate prefixes are computed from the hit counts of the prefixes at the previous level:
|
||||
/// For any prefix `p` whose hit count is at least the desired threshold, add `p || 0` and `p || 1`
|
||||
/// to the list.
|
||||
pub fn generate_zipf_distributed_batch(
|
||||
rng: &mut impl Rng,
|
||||
bits: usize,
|
||||
threshold: usize,
|
||||
measurement_count: usize,
|
||||
zipf_support: usize,
|
||||
zipf_exponent: f64,
|
||||
) -> (Vec<IdpfInput>, Vec<Vec<IdpfInput>>) {
|
||||
// Generate random inputs.
|
||||
let mut inputs = Vec::with_capacity(zipf_support);
|
||||
for _ in 0..zipf_support {
|
||||
let bools: Vec<bool> = (0..bits).map(|_| rng.gen()).collect();
|
||||
inputs.push(IdpfInput::from_bools(&bools));
|
||||
}
|
||||
|
||||
// Sample a number of inputs according to the Zipf distribution.
|
||||
let mut samples = Vec::with_capacity(measurement_count);
|
||||
let zipf = ZipfDistribution::new(zipf_support, zipf_exponent).unwrap();
|
||||
for _ in 0..measurement_count {
|
||||
samples.push(inputs[zipf.sample(rng) - 1].clone());
|
||||
}
|
||||
|
||||
// Compute the prefix tree for the desired threshold.
|
||||
let mut prefix_tree = Vec::with_capacity(bits);
|
||||
prefix_tree.push(vec![
|
||||
IdpfInput::from_bools(&[false]),
|
||||
IdpfInput::from_bools(&[true]),
|
||||
]);
|
||||
|
||||
for level in 0..bits - 1 {
|
||||
// Compute the hit count of each prefix from the previous level.
|
||||
let mut hit_counts = vec![0; prefix_tree[level].len()];
|
||||
for (hit_count, prefix) in hit_counts.iter_mut().zip(prefix_tree[level].iter()) {
|
||||
for sample in samples.iter() {
|
||||
let mut is_prefix = true;
|
||||
for j in 0..prefix.len() {
|
||||
if prefix[j] != sample[j] {
|
||||
is_prefix = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if is_prefix {
|
||||
*hit_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the next set of candidate prefixes.
|
||||
let mut next_prefixes = Vec::with_capacity(prefix_tree.last().unwrap().len());
|
||||
for (hit_count, prefix) in hit_counts.iter().zip(prefix_tree[level].iter()) {
|
||||
if *hit_count >= threshold {
|
||||
next_prefixes.push(prefix.clone_with_suffix(&[false]));
|
||||
next_prefixes.push(prefix.clone_with_suffix(&[true]));
|
||||
}
|
||||
}
|
||||
prefix_tree.push(next_prefixes);
|
||||
}
|
||||
|
||||
(samples, prefix_tree)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::{TryFrom, TryInto},
|
||||
convert::TryInto,
|
||||
io::Cursor,
|
||||
ops::{Add, AddAssign, Sub},
|
||||
str::FromStr,
|
||||
|
@ -1568,16 +1662,16 @@ mod tests {
|
|||
seed: [0xab; 16],
|
||||
control_bits: [Choice::from(1), Choice::from(0)],
|
||||
value: Poplar1IdpfValue::new([
|
||||
Field64::try_from(83261u64).unwrap(),
|
||||
Field64::try_from(125159u64).unwrap(),
|
||||
Field64::from(83261u64),
|
||||
Field64::from(125159u64),
|
||||
]),
|
||||
},
|
||||
IdpfCorrectionWord{
|
||||
seed: [0xcd;16],
|
||||
control_bits: [Choice::from(0), Choice::from(1)],
|
||||
value: Poplar1IdpfValue::new([
|
||||
Field64::try_from(17614120u64).unwrap(),
|
||||
Field64::try_from(20674u64).unwrap(),
|
||||
Field64::from(17614120u64),
|
||||
Field64::from(20674u64),
|
||||
]),
|
||||
},
|
||||
]),
|
||||
|
@ -1605,7 +1699,7 @@ mod tests {
|
|||
"f0debc9a78563412f0debc9a78563412f0debc9a78563412f0debc9a78563412", // field element correction word, continued
|
||||
))
|
||||
.unwrap();
|
||||
let encoded = public_share.get_encoded();
|
||||
let encoded = public_share.get_encoded().unwrap();
|
||||
let decoded = IdpfPublicShare::get_decoded_with_param(&3, &message).unwrap();
|
||||
assert_eq!(public_share, decoded);
|
||||
assert_eq!(message, encoded);
|
||||
|
@ -1692,7 +1786,7 @@ mod tests {
|
|||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
))
|
||||
.unwrap();
|
||||
let encoded = public_share.get_encoded();
|
||||
let encoded = public_share.get_encoded().unwrap();
|
||||
let decoded = IdpfPublicShare::get_decoded_with_param(&9, &message).unwrap();
|
||||
assert_eq!(public_share, decoded);
|
||||
assert_eq!(message, encoded);
|
||||
|
@ -1761,7 +1855,7 @@ mod tests {
|
|||
0,
|
||||
);
|
||||
|
||||
assert_eq!(public_share.get_encoded(), serialized_public_share);
|
||||
assert_eq!(public_share.get_encoded().unwrap(), serialized_public_share);
|
||||
assert_eq!(
|
||||
IdpfPublicShare::get_decoded_with_param(&idpf_bits, &serialized_public_share)
|
||||
.unwrap(),
|
||||
|
@ -1821,7 +1915,7 @@ mod tests {
|
|||
/// Load a test vector for Idpf key generation.
|
||||
fn load_idpfpoplar_test_vector() -> IdpfTestVector {
|
||||
let test_vec: serde_json::Value =
|
||||
serde_json::from_str(include_str!("vdaf/test_vec/07/IdpfPoplar_0.json")).unwrap();
|
||||
serde_json::from_str(include_str!("vdaf/test_vec/08/IdpfPoplar_0.json")).unwrap();
|
||||
let test_vec_obj = test_vec.as_object().unwrap();
|
||||
|
||||
let bits = test_vec_obj
|
||||
|
@ -1939,7 +2033,7 @@ mod tests {
|
|||
public_share, expected_public_share,
|
||||
"public share did not match\n{public_share:#x?}\n{expected_public_share:#x?}"
|
||||
);
|
||||
let encoded_public_share = public_share.get_encoded();
|
||||
let encoded_public_share = public_share.get_encoded().unwrap();
|
||||
assert_eq!(encoded_public_share, test_vector.public_share);
|
||||
}
|
||||
|
||||
|
@ -1988,7 +2082,9 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Encode for MyUnit {
|
||||
fn encode(&self, _: &mut Vec<u8>) {}
|
||||
fn encode(&self, _: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for MyUnit {
|
||||
|
@ -2066,8 +2162,8 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Encode for MyVector {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
encode_u32_items(bytes, &(), &self.0);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
encode_u32_items(bytes, &(), &self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
pub mod benchmarked;
|
||||
pub mod codec;
|
||||
#[cfg(feature = "experimental")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
|
||||
pub mod dp;
|
||||
mod fft;
|
||||
pub mod field;
|
||||
|
@ -32,3 +33,9 @@ mod polynomial;
|
|||
mod prng;
|
||||
pub mod topology;
|
||||
pub mod vdaf;
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(all(feature = "crypto-dependencies", feature = "experimental")))
|
||||
)]
|
||||
pub mod vidpf;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
//! Functions for polynomial interpolation and evaluation
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
use crate::fft::{discrete_fourier_transform, discrete_fourier_transform_inv_finish};
|
||||
use crate::field::FftFriendlyFieldElement;
|
||||
|
||||
|
@ -204,7 +204,7 @@ pub fn poly_mul<F: FftFriendlyFieldElement>(p: &[F], q: &[F]) -> Vec<F> {
|
|||
out
|
||||
}
|
||||
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[inline]
|
||||
pub fn poly_interpret_eval<F: FftFriendlyFieldElement>(
|
||||
points: &[F],
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
//! NOTE: The public API for this module is a work in progress.
|
||||
|
||||
use crate::field::{FieldElement, FieldElementExt};
|
||||
#[cfg(feature = "crypto-dependencies")]
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
use crate::vdaf::xof::SeedStreamAes128;
|
||||
#[cfg(feature = "crypto-dependencies")]
|
||||
use getrandom::getrandom;
|
||||
use crate::vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128};
|
||||
use rand_core::RngCore;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
@ -19,6 +18,7 @@ const BUFFER_SIZE_IN_ELEMENTS: usize = 32;
|
|||
|
||||
/// Errors propagated by methods in this module.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum PrngError {
|
||||
/// Failure when calling getrandom().
|
||||
#[error("getrandom: {0}")]
|
||||
|
@ -35,7 +35,7 @@ pub(crate) struct Prng<F, S> {
|
|||
buffer_index: usize,
|
||||
}
|
||||
|
||||
#[cfg(feature = "crypto-dependencies")]
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
impl<F: FieldElement> Prng<F, SeedStreamAes128> {
|
||||
/// Create a [`Prng`] from a seed for Prio 2. The first 16 bytes of the seed and the last 16
|
||||
/// bytes of the seed are used, respectively, for the key and initialization vector for AES128
|
||||
|
@ -44,12 +44,17 @@ impl<F: FieldElement> Prng<F, SeedStreamAes128> {
|
|||
let seed_stream = SeedStreamAes128::new(&seed[..16], &seed[16..]);
|
||||
Self::from_seed_stream(seed_stream)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: FieldElement> Prng<F, SeedStreamTurboShake128> {
|
||||
/// Create a [`Prng`] from a randomly generated seed.
|
||||
pub(crate) fn new() -> Result<Self, PrngError> {
|
||||
let mut seed = [0; 32];
|
||||
getrandom(&mut seed)?;
|
||||
Ok(Self::from_prio2_seed(&seed))
|
||||
let seed = Seed::generate()?;
|
||||
Ok(Prng::from_seed_stream(XofTurboShake128::seed_stream(
|
||||
&seed,
|
||||
&[],
|
||||
&[],
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,18 +130,20 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[cfg(feature = "experimental")]
|
||||
use crate::field::{encode_fieldvec, Field128, FieldPrio2};
|
||||
use crate::{
|
||||
codec::Decode,
|
||||
field::{Field64, FieldPrio2},
|
||||
vdaf::xof::{Seed, SeedStreamSha3, Xof, XofShake128},
|
||||
field::Field64,
|
||||
vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128},
|
||||
};
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
use base64::{engine::Engine, prelude::BASE64_STANDARD};
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn secret_sharing_interop() {
|
||||
let seed = [
|
||||
0xcd, 0x85, 0x5b, 0xd4, 0x86, 0x48, 0xa4, 0xce, 0x52, 0x5c, 0x36, 0xee, 0x5a, 0x71,
|
||||
|
@ -158,21 +165,22 @@ mod tests {
|
|||
}
|
||||
|
||||
/// takes a seed and hash as base64 encoded strings
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn random_data_interop(seed_base64: &str, hash_base64: &str, len: usize) {
|
||||
let seed = BASE64_STANDARD.decode(seed_base64).unwrap();
|
||||
let random_data = extract_share_from_seed::<FieldPrio2>(len, &seed);
|
||||
|
||||
let random_bytes = FieldPrio2::slice_into_byte_vec(&random_data);
|
||||
let mut random_bytes = Vec::new();
|
||||
encode_fieldvec(&random_data, &mut random_bytes).unwrap();
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
let mut hasher = <Sha256 as Digest>::new();
|
||||
hasher.update(&random_bytes);
|
||||
let digest = hasher.finalize();
|
||||
assert_eq!(BASE64_STANDARD.encode(digest), hash_base64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg(feature = "experimental")]
|
||||
fn test_hash_interop() {
|
||||
random_data_interop(
|
||||
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
||||
|
@ -206,6 +214,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
fn extract_share_from_seed<F: FieldElement>(length: usize, seed: &[u8]) -> Vec<F> {
|
||||
assert_eq!(seed.len(), 32);
|
||||
Prng::from_prio2_seed(seed.try_into().unwrap())
|
||||
|
@ -218,22 +227,22 @@ mod tests {
|
|||
// These constants were found in a brute-force search, and they test that the XOF performs
|
||||
// rejection sampling correctly when the raw output exceeds the prime modulus.
|
||||
let seed = Seed::get_decoded(&[
|
||||
0x29, 0xb2, 0x98, 0x64, 0xb4, 0xaa, 0x4e, 0x07, 0x2a, 0x44, 0x49, 0x24, 0xf6, 0x74,
|
||||
0x0a, 0x3d,
|
||||
0xd5, 0x3f, 0xff, 0x5d, 0x88, 0x8c, 0x60, 0x4e, 0x9f, 0x24, 0x16, 0xe1, 0xa2, 0x0a,
|
||||
0x62, 0x34,
|
||||
])
|
||||
.unwrap();
|
||||
let expected = Field64::from(2035552711764301796);
|
||||
let expected = Field64::from(3401316594827516850);
|
||||
|
||||
let seed_stream = XofShake128::seed_stream(&seed, b"", b"");
|
||||
let seed_stream = XofTurboShake128::seed_stream(&seed, b"", b"");
|
||||
let mut prng = Prng::<Field64, _>::from_seed_stream(seed_stream);
|
||||
let actual = prng.nth(33236).unwrap();
|
||||
let actual = prng.nth(662).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
{
|
||||
let mut seed_stream = XofShake128::seed_stream(&seed, b"", b"");
|
||||
let mut seed_stream = XofTurboShake128::seed_stream(&seed, b"", b"");
|
||||
let mut actual = <Field64 as FieldElement>::zero();
|
||||
for _ in 0..=33236 {
|
||||
for _ in 0..=662 {
|
||||
actual = <Field64 as crate::idpf::IdpfValue>::generate(&mut seed_stream, &());
|
||||
}
|
||||
assert_eq!(actual, expected);
|
||||
|
@ -246,12 +255,12 @@ mod tests {
|
|||
fn left_over_buffer_back_fill() {
|
||||
let seed = Seed::generate().unwrap();
|
||||
|
||||
let mut prng: Prng<Field64, SeedStreamSha3> =
|
||||
Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
|
||||
let mut prng: Prng<Field64, SeedStreamTurboShake128> =
|
||||
Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
|
||||
|
||||
// Construct a `Prng` with a longer-than-usual buffer.
|
||||
let mut prng_weird_buffer_size: Prng<Field64, SeedStreamSha3> =
|
||||
Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
|
||||
let mut prng_weird_buffer_size: Prng<Field64, SeedStreamTurboShake128> =
|
||||
Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
|
||||
let mut extra = [0; 7];
|
||||
prng_weird_buffer_size.seed_stream.fill_bytes(&mut extra);
|
||||
prng_weird_buffer_size.buffer.extend_from_slice(&extra);
|
||||
|
@ -265,13 +274,13 @@ mod tests {
|
|||
|
||||
#[cfg(feature = "experimental")]
|
||||
#[test]
|
||||
fn into_new_field() {
|
||||
fn into_different_field() {
|
||||
let seed = Seed::generate().unwrap();
|
||||
let want: Prng<Field64, SeedStreamSha3> =
|
||||
Prng::from_seed_stream(XofShake128::seed_stream(&seed, b"", b""));
|
||||
let want: Prng<Field64, SeedStreamTurboShake128> =
|
||||
Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b""));
|
||||
let want_buffer = want.buffer.clone();
|
||||
|
||||
let got: Prng<FieldPrio2, _> = want.into_new_field();
|
||||
let got: Prng<Field128, _> = want.into_new_field();
|
||||
assert_eq!(got.buffer_index, 0);
|
||||
assert_eq!(got.buffer, want_buffer);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! two aggregators, designated "Leader" and "Helper". This topology is required for implementing
|
||||
//! the [Distributed Aggregation Protocol][DAP].
|
||||
//!
|
||||
//! [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
//! [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
//! [DAP]: https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap
|
||||
|
||||
use crate::{
|
||||
|
@ -15,6 +15,7 @@ use std::fmt::Debug;
|
|||
|
||||
/// Errors emitted by this module.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum PingPongError {
|
||||
/// Error running prepare_init
|
||||
#[error("vdaf.prepare_init: {0}")]
|
||||
|
@ -28,12 +29,12 @@ pub enum PingPongError {
|
|||
#[error("vdaf.prepare_next {0}")]
|
||||
VdafPrepareNext(VdafError),
|
||||
|
||||
/// Error decoding a prepare share
|
||||
#[error("decode prep share {0}")]
|
||||
/// Error encoding or decoding a prepare share
|
||||
#[error("encode/decode prep share {0}")]
|
||||
CodecPrepShare(CodecError),
|
||||
|
||||
/// Error decoding a prepare message
|
||||
#[error("decode prep message {0}")]
|
||||
/// Error encoding or decoding a prepare message
|
||||
#[error("encode/decode prep message {0}")]
|
||||
CodecPrepMessage(CodecError),
|
||||
|
||||
/// Host is in an unexpected state
|
||||
|
@ -63,7 +64,7 @@ pub enum PingPongError {
|
|||
/// variants are opaque byte buffers. This is because the ping-pong routines take responsibility for
|
||||
/// decoding preparation shares and messages, which usually requires having the preparation state.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum PingPongMessage {
|
||||
/// Corresponds to MessageType.initialize.
|
||||
|
@ -108,27 +109,28 @@ impl Debug for PingPongMessage {
|
|||
}
|
||||
|
||||
impl Encode for PingPongMessage {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
// The encoding includes an implicit discriminator byte, called MessageType in the VDAF
|
||||
// spec.
|
||||
match self {
|
||||
Self::Initialize { prep_share } => {
|
||||
0u8.encode(bytes);
|
||||
encode_u32_items(bytes, &(), prep_share);
|
||||
0u8.encode(bytes)?;
|
||||
encode_u32_items(bytes, &(), prep_share)?;
|
||||
}
|
||||
Self::Continue {
|
||||
prep_msg,
|
||||
prep_share,
|
||||
} => {
|
||||
1u8.encode(bytes);
|
||||
encode_u32_items(bytes, &(), prep_msg);
|
||||
encode_u32_items(bytes, &(), prep_share);
|
||||
1u8.encode(bytes)?;
|
||||
encode_u32_items(bytes, &(), prep_msg)?;
|
||||
encode_u32_items(bytes, &(), prep_share)?;
|
||||
}
|
||||
Self::Finish { prep_msg } => {
|
||||
2u8.encode(bytes);
|
||||
encode_u32_items(bytes, &(), prep_msg);
|
||||
2u8.encode(bytes)?;
|
||||
encode_u32_items(bytes, &(), prep_msg)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -182,7 +184,7 @@ impl Decode for PingPongMessage {
|
|||
/// preprocessed prepare message. Their encoding is much smaller than the `(State, Message)` tuple,
|
||||
/// which can always be recomputed with [`Self::evaluate`].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
pub struct PingPongTransition<
|
||||
const VERIFY_KEY_SIZE: usize,
|
||||
|
@ -212,26 +214,31 @@ impl<
|
|||
),
|
||||
PingPongError,
|
||||
> {
|
||||
let prep_msg = self.current_prepare_message.get_encoded();
|
||||
let prep_msg = self
|
||||
.current_prepare_message
|
||||
.get_encoded()
|
||||
.map_err(PingPongError::CodecPrepMessage)?;
|
||||
|
||||
vdaf.prepare_next(
|
||||
self.previous_prepare_state.clone(),
|
||||
self.current_prepare_message.clone(),
|
||||
)
|
||||
.map(|transition| match transition {
|
||||
PrepareTransition::Continue(prep_state, prep_share) => (
|
||||
.map_err(PingPongError::VdafPrepareNext)
|
||||
.and_then(|transition| match transition {
|
||||
PrepareTransition::Continue(prep_state, prep_share) => Ok((
|
||||
PingPongState::Continued(prep_state),
|
||||
PingPongMessage::Continue {
|
||||
prep_msg,
|
||||
prep_share: prep_share.get_encoded(),
|
||||
prep_share: prep_share
|
||||
.get_encoded()
|
||||
.map_err(PingPongError::CodecPrepShare)?,
|
||||
},
|
||||
),
|
||||
PrepareTransition::Finish(output_share) => (
|
||||
)),
|
||||
PrepareTransition::Finish(output_share) => Ok((
|
||||
PingPongState::Finished(output_share),
|
||||
PingPongMessage::Finish { prep_msg },
|
||||
),
|
||||
)),
|
||||
})
|
||||
.map_err(PingPongError::VdafPrepareNext)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,9 +260,9 @@ where
|
|||
A: Aggregator<VERIFY_KEY_SIZE, NONCE_SIZE>,
|
||||
A::PrepareState: Encode,
|
||||
{
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.previous_prepare_state.encode(bytes);
|
||||
self.current_prepare_message.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.previous_prepare_state.encode(bytes)?;
|
||||
self.current_prepare_message.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -293,7 +300,7 @@ where
|
|||
/// code, and the `Rejected` state is represented as `std::result::Result::Err`, so this enum does
|
||||
/// not include those variants.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum PingPongState<
|
||||
const VERIFY_KEY_SIZE: usize,
|
||||
|
@ -331,7 +338,7 @@ pub enum PingPongContinuedValue<
|
|||
|
||||
/// Extension trait on [`crate::vdaf::Aggregator`] which adds the [VDAF Ping-Pong Topology][VDAF].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>:
|
||||
Aggregator<VERIFY_KEY_SIZE, NONCE_SIZE>
|
||||
{
|
||||
|
@ -351,7 +358,7 @@ pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize
|
|||
/// leader along with the next [`PingPongMessage`] received from the helper as input to
|
||||
/// [`Self::leader_continued`] to advance to the next round.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
fn leader_initialized(
|
||||
&self,
|
||||
verify_key: &[u8; VERIFY_KEY_SIZE],
|
||||
|
@ -362,7 +369,7 @@ pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize
|
|||
) -> Result<(Self::State, PingPongMessage), PingPongError>;
|
||||
|
||||
/// Initialize helper state using the helper's input share and the leader's first prepare share.
|
||||
/// Corresponds to `ping_pong_helper_init` in the forthcoming `draft-irtf-cfrg-vdaf-07`.
|
||||
/// Corresponds to `ping_pong_helper_init` in [VDAF].
|
||||
///
|
||||
/// If successful, the returned [`PingPongTransition`] should be evaluated, yielding a
|
||||
/// [`PingPongMessage`], which should be transmitted to the leader, and a [`PingPongState`].
|
||||
|
@ -378,6 +385,8 @@ pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize
|
|||
/// # Errors
|
||||
///
|
||||
/// `inbound` must be `PingPongMessage::Initialize` or the function will fail.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
fn helper_initialized(
|
||||
&self,
|
||||
verify_key: &[u8; VERIFY_KEY_SIZE],
|
||||
|
@ -415,15 +424,7 @@ pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize
|
|||
///
|
||||
/// `inbound` must not be `PingPongMessage::Initialize` or the function will fail.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// The specification of this function in [VDAF] takes the aggregation parameter. This version
|
||||
/// does not, because [`crate::vdaf::Aggregator::prepare_preprocess`] does not take the
|
||||
/// aggregation parameter. This may change in the future if/when [#670][issue] is addressed.
|
||||
///
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [issue]: https://github.com/divviup/libprio-rs/issues/670
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
fn leader_continued(
|
||||
&self,
|
||||
leader_state: Self::State,
|
||||
|
@ -458,15 +459,7 @@ pub trait PingPongTopology<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize
|
|||
///
|
||||
/// `inbound` must not be `PingPongMessage::Initialize` or the function will fail.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// The specification of this function in [VDAF] takes the aggregation parameter. This version
|
||||
/// does not, because [`crate::vdaf::Aggregator::prepare_preprocess`] does not take the
|
||||
/// aggregation parameter. This may change in the future if/when [#670][issue] is addressed.
|
||||
///
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.8
|
||||
/// [issue]: https://github.com/divviup/libprio-rs/issues/670
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.8
|
||||
fn helper_continued(
|
||||
&self,
|
||||
helper_state: Self::State,
|
||||
|
@ -513,15 +506,17 @@ where
|
|||
public_share,
|
||||
input_share,
|
||||
)
|
||||
.map(|(prep_state, prep_share)| {
|
||||
(
|
||||
.map_err(PingPongError::VdafPrepareInit)
|
||||
.and_then(|(prep_state, prep_share)| {
|
||||
Ok((
|
||||
PingPongState::Continued(prep_state),
|
||||
PingPongMessage::Initialize {
|
||||
prep_share: prep_share.get_encoded(),
|
||||
prep_share: prep_share
|
||||
.get_encoded()
|
||||
.map_err(PingPongError::CodecPrepShare)?,
|
||||
},
|
||||
)
|
||||
))
|
||||
})
|
||||
.map_err(PingPongError::VdafPrepareInit)
|
||||
}
|
||||
|
||||
fn helper_initialized(
|
||||
|
@ -652,18 +647,14 @@ where
|
|||
(PrepareTransition::Finish(output_share), None) => {
|
||||
Ok(PingPongContinuedValue::FinishedNoMessage { output_share })
|
||||
}
|
||||
(PrepareTransition::Continue(_, _), None) => {
|
||||
return Err(PingPongError::PeerMessageMismatch {
|
||||
found: inbound.variant(),
|
||||
expected: "continue",
|
||||
})
|
||||
}
|
||||
(PrepareTransition::Finish(_), Some(_)) => {
|
||||
return Err(PingPongError::PeerMessageMismatch {
|
||||
found: inbound.variant(),
|
||||
expected: "finish",
|
||||
})
|
||||
}
|
||||
(PrepareTransition::Continue(_, _), None) => Err(PingPongError::PeerMessageMismatch {
|
||||
found: inbound.variant(),
|
||||
expected: "continue",
|
||||
}),
|
||||
(PrepareTransition::Finish(_), Some(_)) => Err(PingPongError::PeerMessageMismatch {
|
||||
found: inbound.variant(),
|
||||
expected: "finish",
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -914,7 +905,7 @@ mod tests {
|
|||
|
||||
for (message, expected_hex) in messages {
|
||||
let mut encoded_val = Vec::new();
|
||||
message.encode(&mut encoded_val);
|
||||
message.encode(&mut encoded_val).unwrap();
|
||||
let got_hex = hex::encode(&encoded_val);
|
||||
assert_eq!(
|
||||
&got_hex, expected_hex,
|
||||
|
@ -942,7 +933,7 @@ mod tests {
|
|||
current_prepare_message: (),
|
||||
};
|
||||
|
||||
let encoded = transition.get_encoded();
|
||||
let encoded = transition.get_encoded().unwrap();
|
||||
let hex_encoded = hex::encode(&encoded);
|
||||
|
||||
assert_eq!(
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! Verifiable Distributed Aggregation Functions (VDAFs) as described in
|
||||
//! [[draft-irtf-cfrg-vdaf-07]].
|
||||
//! [[draft-irtf-cfrg-vdaf-08]].
|
||||
//!
|
||||
//! [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
//! [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
use crate::dp::DifferentialPrivacyStrategy;
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
use crate::idpf::IdpfError;
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
use crate::vidpf::VidpfError;
|
||||
use crate::{
|
||||
codec::{CodecError, Decode, Encode, ParameterizedDecode},
|
||||
field::{encode_fieldvec, merge_vector, FieldElement, FieldError},
|
||||
|
@ -17,15 +19,16 @@ use crate::{
|
|||
vdaf::xof::Seed,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt::Debug, io::Cursor};
|
||||
use std::{error::Error, fmt::Debug, io::Cursor};
|
||||
use subtle::{Choice, ConstantTimeEq};
|
||||
|
||||
/// A component of the domain-separation tag, used to bind the VDAF operations to the document
|
||||
/// version. This will be revised with each draft with breaking changes.
|
||||
pub(crate) const VERSION: u8 = 7;
|
||||
pub(crate) const VERSION: u8 = 8;
|
||||
|
||||
/// Errors emitted by this module.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum VdafError {
|
||||
/// An error occurred.
|
||||
#[error("vdaf error: {0}")]
|
||||
|
@ -55,6 +58,15 @@ pub enum VdafError {
|
|||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[error("idpf error: {0}")]
|
||||
Idpf(#[from] IdpfError),
|
||||
|
||||
/// VIDPF error.
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[error("vidpf error: {0}")]
|
||||
Vidpf(#[from] VidpfError),
|
||||
|
||||
/// Errors from other VDAFs.
|
||||
#[error(transparent)]
|
||||
Other(Box<dyn Error + 'static + Send + Sync>),
|
||||
}
|
||||
|
||||
/// An additive share of a vector of field elements.
|
||||
|
@ -67,18 +79,6 @@ pub enum Share<F, const SEED_SIZE: usize> {
|
|||
Helper(Seed<SEED_SIZE>),
|
||||
}
|
||||
|
||||
impl<F: Clone, const SEED_SIZE: usize> Share<F, SEED_SIZE> {
|
||||
/// Truncate the Leader's share to the given length. If this is the Helper's share, then this
|
||||
/// method clones the input without modifying it.
|
||||
#[cfg(feature = "prio2")]
|
||||
pub(crate) fn truncated(&self, len: usize) -> Self {
|
||||
match self {
|
||||
Self::Leader(ref data) => Self::Leader(data[..len].to_vec()),
|
||||
Self::Helper(ref seed) => Self::Helper(seed.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: ConstantTimeEq, const SEED_SIZE: usize> PartialEq for Share<F, SEED_SIZE> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.ct_eq(other).into()
|
||||
|
@ -130,16 +130,15 @@ impl<F: FieldElement, const SEED_SIZE: usize> ParameterizedDecode<ShareDecodingP
|
|||
}
|
||||
|
||||
impl<F: FieldElement, const SEED_SIZE: usize> Encode for Share<F, SEED_SIZE> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
match self {
|
||||
Share::Leader(share_data) => {
|
||||
for x in share_data {
|
||||
x.encode(bytes);
|
||||
x.encode(bytes)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Share::Helper(share_seed) => {
|
||||
share_seed.encode(bytes);
|
||||
}
|
||||
Share::Helper(share_seed) => share_seed.encode(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,9 +157,6 @@ impl<F: FieldElement, const SEED_SIZE: usize> Encode for Share<F, SEED_SIZE> {
|
|||
/// and [`Collector`], which define the roles of the various parties involved in the execution of
|
||||
/// the VDAF.
|
||||
pub trait Vdaf: Clone + Debug {
|
||||
/// Algorithm identifier for this VDAF.
|
||||
const ID: u32;
|
||||
|
||||
/// The type of Client measurement to be aggregated.
|
||||
type Measurement: Clone + Debug;
|
||||
|
||||
|
@ -188,17 +184,20 @@ pub trait Vdaf: Clone + Debug {
|
|||
+ for<'a> ParameterizedDecode<(&'a Self, &'a Self::AggregationParam)>
|
||||
+ Encode;
|
||||
|
||||
/// Return the VDAF's algorithm ID.
|
||||
fn algorithm_id(&self) -> u32;
|
||||
|
||||
/// The number of Aggregators. The Client generates as many input shares as there are
|
||||
/// Aggregators.
|
||||
fn num_aggregators(&self) -> usize;
|
||||
|
||||
/// Generate the domain separation tag for this VDAF. The output is used for domain separation
|
||||
/// by the XOF.
|
||||
fn domain_separation_tag(usage: u16) -> [u8; 8] {
|
||||
fn domain_separation_tag(&self, usage: u16) -> [u8; 8] {
|
||||
let mut dst = [0_u8; 8];
|
||||
dst[0] = VERSION;
|
||||
dst[1] = 0; // algorithm class
|
||||
dst[2..6].copy_from_slice(&(Self::ID).to_be_bytes());
|
||||
dst[2..6].copy_from_slice(&(self.algorithm_id()).to_be_bytes());
|
||||
dst[6..8].copy_from_slice(&usage.to_be_bytes());
|
||||
dst
|
||||
}
|
||||
|
@ -211,7 +210,7 @@ pub trait Client<const NONCE_SIZE: usize>: Vdaf {
|
|||
///
|
||||
/// Implements `Vdaf::shard` from [VDAF].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.1
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.1
|
||||
fn shard(
|
||||
&self,
|
||||
measurement: &Self::Measurement,
|
||||
|
@ -247,7 +246,7 @@ pub trait Aggregator<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>: Vda
|
|||
///
|
||||
/// Implements `Vdaf.prep_init` from [VDAF].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.2
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.2
|
||||
fn prepare_init(
|
||||
&self,
|
||||
verify_key: &[u8; VERIFY_KEY_SIZE],
|
||||
|
@ -262,29 +261,7 @@ pub trait Aggregator<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>: Vda
|
|||
///
|
||||
/// Implements `Vdaf.prep_shares_to_prep` from [VDAF].
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// [`Self::prepare_shares_to_prepare_message`] is preferable since its name better matches the
|
||||
/// specification.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.2
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use Vdaf::prepare_shares_to_prepare_message instead"
|
||||
)]
|
||||
fn prepare_preprocess<M: IntoIterator<Item = Self::PrepareShare>>(
|
||||
&self,
|
||||
agg_param: &Self::AggregationParam,
|
||||
inputs: M,
|
||||
) -> Result<Self::PrepareMessage, VdafError> {
|
||||
self.prepare_shares_to_prepare_message(agg_param, inputs)
|
||||
}
|
||||
|
||||
/// Preprocess a round of preparation shares into a single input to [`Self::prepare_next`].
|
||||
///
|
||||
/// Implements `Vdaf.prep_shares_to_prep` from [VDAF].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.2
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.2
|
||||
fn prepare_shares_to_prepare_message<M: IntoIterator<Item = Self::PrepareShare>>(
|
||||
&self,
|
||||
agg_param: &Self::AggregationParam,
|
||||
|
@ -301,31 +278,7 @@ pub trait Aggregator<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>: Vda
|
|||
///
|
||||
/// Implements `Vdaf.prep_next` from [VDAF].
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// [`Self::prepare_next`] is preferable since its name better matches the specification.
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.2
|
||||
#[deprecated(since = "0.15.0", note = "Use Vdaf::prepare_next")]
|
||||
fn prepare_step(
|
||||
&self,
|
||||
state: Self::PrepareState,
|
||||
input: Self::PrepareMessage,
|
||||
) -> Result<PrepareTransition<Self, VERIFY_KEY_SIZE, NONCE_SIZE>, VdafError> {
|
||||
self.prepare_next(state, input)
|
||||
}
|
||||
|
||||
/// Compute the next state transition from the current state and the previous round of input
|
||||
/// messages. If this returns [`PrepareTransition::Continue`], then the returned
|
||||
/// [`Self::PrepareShare`] should be combined with the other Aggregators' `PrepareShare`s from
|
||||
/// this round and passed into another call to this method. This continues until this method
|
||||
/// returns [`PrepareTransition::Finish`], at which point the returned output share may be
|
||||
/// aggregated. If the method returns an error, the aggregator should consider its input share
|
||||
/// invalid and not attempt to process it any further.
|
||||
///
|
||||
/// Implements `Vdaf.prep_next` from [VDAF].
|
||||
///
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-07#section-5.2
|
||||
/// [VDAF]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-08#section-5.2
|
||||
fn prepare_next(
|
||||
&self,
|
||||
state: Self::PrepareState,
|
||||
|
@ -342,6 +295,7 @@ pub trait Aggregator<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>: Vda
|
|||
|
||||
/// Aggregator that implements differential privacy with Aggregator-side noise addition.
|
||||
#[cfg(feature = "experimental")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
|
||||
pub trait AggregatorWithNoise<
|
||||
const VERIFY_KEY_SIZE: usize,
|
||||
const NONCE_SIZE: usize,
|
||||
|
@ -428,7 +382,7 @@ impl<F> From<Vec<F>> for OutputShare<F> {
|
|||
}
|
||||
|
||||
impl<F: FieldElement> Encode for OutputShare<F> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
encode_fieldvec(&self.0, bytes)
|
||||
}
|
||||
|
||||
|
@ -451,6 +405,12 @@ impl<F> Debug for OutputShare<F> {
|
|||
|
||||
pub struct AggregateShare<F>(Vec<F>);
|
||||
|
||||
impl<F> From<Vec<F>> for AggregateShare<F> {
|
||||
fn from(other: Vec<F>) -> Self {
|
||||
Self(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: ConstantTimeEq> PartialEq for AggregateShare<F> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.ct_eq(other).into()
|
||||
|
@ -498,7 +458,7 @@ impl<F: FieldElement> AggregateShare<F> {
|
|||
}
|
||||
|
||||
impl<F: FieldElement> Encode for AggregateShare<F> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
encode_fieldvec(&self.0, bytes)
|
||||
}
|
||||
|
||||
|
@ -507,151 +467,190 @@ impl<F: FieldElement> Encode for AggregateShare<F> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn run_vdaf<V, M, const SEED_SIZE: usize>(
|
||||
vdaf: &V,
|
||||
agg_param: &V::AggregationParam,
|
||||
measurements: M,
|
||||
) -> Result<V::AggregateResult, VdafError>
|
||||
where
|
||||
V: Client<16> + Aggregator<SEED_SIZE, 16> + Collector,
|
||||
M: IntoIterator<Item = V::Measurement>,
|
||||
{
|
||||
/// Utilities for testing VDAFs.
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub mod test_utils {
|
||||
use super::{Aggregatable, Aggregator, Client, Collector, PrepareTransition, VdafError};
|
||||
use crate::codec::{Encode, ParameterizedDecode};
|
||||
use rand::prelude::*;
|
||||
let mut rng = thread_rng();
|
||||
let mut verify_key = [0; SEED_SIZE];
|
||||
rng.fill(&mut verify_key[..]);
|
||||
|
||||
let mut agg_shares: Vec<Option<V::AggregateShare>> = vec![None; vdaf.num_aggregators()];
|
||||
let mut num_measurements: usize = 0;
|
||||
for measurement in measurements.into_iter() {
|
||||
num_measurements += 1;
|
||||
let nonce = rng.gen();
|
||||
let (public_share, input_shares) = vdaf.shard(&measurement, &nonce)?;
|
||||
let out_shares = run_vdaf_prepare(
|
||||
vdaf,
|
||||
&verify_key,
|
||||
agg_param,
|
||||
&nonce,
|
||||
public_share,
|
||||
input_shares,
|
||||
)?;
|
||||
for (out_share, agg_share) in out_shares.into_iter().zip(agg_shares.iter_mut()) {
|
||||
// Check serialization of output shares
|
||||
let encoded_out_share = out_share.get_encoded();
|
||||
let round_trip_out_share =
|
||||
V::OutputShare::get_decoded_with_param(&(vdaf, agg_param), &encoded_out_share)
|
||||
/// Execute the VDAF end-to-end and return the aggregate result.
|
||||
pub fn run_vdaf<V, M, const SEED_SIZE: usize>(
|
||||
vdaf: &V,
|
||||
agg_param: &V::AggregationParam,
|
||||
measurements: M,
|
||||
) -> Result<V::AggregateResult, VdafError>
|
||||
where
|
||||
V: Client<16> + Aggregator<SEED_SIZE, 16> + Collector,
|
||||
M: IntoIterator<Item = V::Measurement>,
|
||||
{
|
||||
let mut sharded_measurements = Vec::new();
|
||||
for measurement in measurements.into_iter() {
|
||||
let nonce = random();
|
||||
let (public_share, input_shares) = vdaf.shard(&measurement, &nonce)?;
|
||||
|
||||
sharded_measurements.push((public_share, nonce, input_shares));
|
||||
}
|
||||
|
||||
run_vdaf_sharded(vdaf, agg_param, sharded_measurements)
|
||||
}
|
||||
|
||||
/// Execute the VDAF on sharded measurements and return the aggregate result.
|
||||
pub fn run_vdaf_sharded<V, M, I, const SEED_SIZE: usize>(
|
||||
vdaf: &V,
|
||||
agg_param: &V::AggregationParam,
|
||||
sharded_measurements: M,
|
||||
) -> Result<V::AggregateResult, VdafError>
|
||||
where
|
||||
V: Client<16> + Aggregator<SEED_SIZE, 16> + Collector,
|
||||
M: IntoIterator<Item = (V::PublicShare, [u8; 16], I)>,
|
||||
I: IntoIterator<Item = V::InputShare>,
|
||||
{
|
||||
let mut rng = thread_rng();
|
||||
let mut verify_key = [0; SEED_SIZE];
|
||||
rng.fill(&mut verify_key[..]);
|
||||
|
||||
let mut agg_shares: Vec<Option<V::AggregateShare>> = vec![None; vdaf.num_aggregators()];
|
||||
let mut num_measurements: usize = 0;
|
||||
for (public_share, nonce, input_shares) in sharded_measurements.into_iter() {
|
||||
num_measurements += 1;
|
||||
let out_shares = run_vdaf_prepare(
|
||||
vdaf,
|
||||
&verify_key,
|
||||
agg_param,
|
||||
&nonce,
|
||||
public_share,
|
||||
input_shares,
|
||||
)?;
|
||||
for (out_share, agg_share) in out_shares.into_iter().zip(agg_shares.iter_mut()) {
|
||||
// Check serialization of output shares
|
||||
let encoded_out_share = out_share.get_encoded().unwrap();
|
||||
let round_trip_out_share =
|
||||
V::OutputShare::get_decoded_with_param(&(vdaf, agg_param), &encoded_out_share)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
round_trip_out_share.get_encoded().unwrap(),
|
||||
encoded_out_share
|
||||
);
|
||||
|
||||
let this_agg_share = V::AggregateShare::from(out_share);
|
||||
if let Some(ref mut inner) = agg_share {
|
||||
inner.merge(&this_agg_share)?;
|
||||
} else {
|
||||
*agg_share = Some(this_agg_share);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for agg_share in agg_shares.iter() {
|
||||
// Check serialization of aggregate shares
|
||||
let encoded_agg_share = agg_share.as_ref().unwrap().get_encoded().unwrap();
|
||||
let round_trip_agg_share =
|
||||
V::AggregateShare::get_decoded_with_param(&(vdaf, agg_param), &encoded_agg_share)
|
||||
.unwrap();
|
||||
assert_eq!(round_trip_out_share.get_encoded(), encoded_out_share);
|
||||
|
||||
let this_agg_share = V::AggregateShare::from(out_share);
|
||||
if let Some(ref mut inner) = agg_share {
|
||||
inner.merge(&this_agg_share)?;
|
||||
} else {
|
||||
*agg_share = Some(this_agg_share);
|
||||
}
|
||||
assert_eq!(
|
||||
round_trip_agg_share.get_encoded().unwrap(),
|
||||
encoded_agg_share
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for agg_share in agg_shares.iter() {
|
||||
// Check serialization of aggregate shares
|
||||
let encoded_agg_share = agg_share.as_ref().unwrap().get_encoded();
|
||||
let round_trip_agg_share =
|
||||
V::AggregateShare::get_decoded_with_param(&(vdaf, agg_param), &encoded_agg_share)
|
||||
.unwrap();
|
||||
assert_eq!(round_trip_agg_share.get_encoded(), encoded_agg_share);
|
||||
}
|
||||
|
||||
let res = vdaf.unshard(
|
||||
agg_param,
|
||||
agg_shares.into_iter().map(|option| option.unwrap()),
|
||||
num_measurements,
|
||||
)?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn run_vdaf_prepare<V, M, const SEED_SIZE: usize>(
|
||||
vdaf: &V,
|
||||
verify_key: &[u8; SEED_SIZE],
|
||||
agg_param: &V::AggregationParam,
|
||||
nonce: &[u8; 16],
|
||||
public_share: V::PublicShare,
|
||||
input_shares: M,
|
||||
) -> Result<Vec<V::OutputShare>, VdafError>
|
||||
where
|
||||
V: Client<16> + Aggregator<SEED_SIZE, 16> + Collector,
|
||||
M: IntoIterator<Item = V::InputShare>,
|
||||
{
|
||||
let input_shares = input_shares
|
||||
.into_iter()
|
||||
.map(|input_share| input_share.get_encoded());
|
||||
|
||||
let mut states = Vec::new();
|
||||
let mut outbound = Vec::new();
|
||||
for (agg_id, input_share) in input_shares.enumerate() {
|
||||
let (state, msg) = vdaf.prepare_init(
|
||||
verify_key,
|
||||
agg_id,
|
||||
let res = vdaf.unshard(
|
||||
agg_param,
|
||||
nonce,
|
||||
&public_share,
|
||||
&V::InputShare::get_decoded_with_param(&(vdaf, agg_id), &input_share)
|
||||
.expect("failed to decode input share"),
|
||||
agg_shares.into_iter().map(|option| option.unwrap()),
|
||||
num_measurements,
|
||||
)?;
|
||||
states.push(state);
|
||||
outbound.push(msg.get_encoded());
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
let mut inbound = vdaf
|
||||
.prepare_shares_to_prepare_message(
|
||||
agg_param,
|
||||
outbound.iter().map(|encoded| {
|
||||
V::PrepareShare::get_decoded_with_param(&states[0], encoded)
|
||||
.expect("failed to decode prep share")
|
||||
}),
|
||||
)?
|
||||
.get_encoded();
|
||||
/// Execute VDAF preparation for a single report and return the recovered output shares.
|
||||
pub fn run_vdaf_prepare<V, M, const SEED_SIZE: usize>(
|
||||
vdaf: &V,
|
||||
verify_key: &[u8; SEED_SIZE],
|
||||
agg_param: &V::AggregationParam,
|
||||
nonce: &[u8; 16],
|
||||
public_share: V::PublicShare,
|
||||
input_shares: M,
|
||||
) -> Result<Vec<V::OutputShare>, VdafError>
|
||||
where
|
||||
V: Client<16> + Aggregator<SEED_SIZE, 16> + Collector,
|
||||
M: IntoIterator<Item = V::InputShare>,
|
||||
{
|
||||
let public_share =
|
||||
V::PublicShare::get_decoded_with_param(vdaf, &public_share.get_encoded().unwrap())
|
||||
.unwrap();
|
||||
let input_shares = input_shares
|
||||
.into_iter()
|
||||
.map(|input_share| input_share.get_encoded().unwrap());
|
||||
|
||||
let mut out_shares = Vec::new();
|
||||
loop {
|
||||
let mut states = Vec::new();
|
||||
let mut outbound = Vec::new();
|
||||
for state in states.iter_mut() {
|
||||
match vdaf.prepare_next(
|
||||
state.clone(),
|
||||
V::PrepareMessage::get_decoded_with_param(state, &inbound)
|
||||
.expect("failed to decode prep message"),
|
||||
)? {
|
||||
PrepareTransition::Continue(new_state, msg) => {
|
||||
outbound.push(msg.get_encoded());
|
||||
*state = new_state
|
||||
}
|
||||
PrepareTransition::Finish(out_share) => {
|
||||
out_shares.push(out_share);
|
||||
for (agg_id, input_share) in input_shares.enumerate() {
|
||||
let (state, msg) = vdaf.prepare_init(
|
||||
verify_key,
|
||||
agg_id,
|
||||
agg_param,
|
||||
nonce,
|
||||
&public_share,
|
||||
&V::InputShare::get_decoded_with_param(&(vdaf, agg_id), &input_share)
|
||||
.expect("failed to decode input share"),
|
||||
)?;
|
||||
states.push(state);
|
||||
outbound.push(msg.get_encoded().unwrap());
|
||||
}
|
||||
|
||||
let mut inbound = vdaf
|
||||
.prepare_shares_to_prepare_message(
|
||||
agg_param,
|
||||
outbound.iter().map(|encoded| {
|
||||
V::PrepareShare::get_decoded_with_param(&states[0], encoded)
|
||||
.expect("failed to decode prep share")
|
||||
}),
|
||||
)?
|
||||
.get_encoded()
|
||||
.unwrap();
|
||||
|
||||
let mut out_shares = Vec::new();
|
||||
loop {
|
||||
let mut outbound = Vec::new();
|
||||
for state in states.iter_mut() {
|
||||
match vdaf.prepare_next(
|
||||
state.clone(),
|
||||
V::PrepareMessage::get_decoded_with_param(state, &inbound)
|
||||
.expect("failed to decode prep message"),
|
||||
)? {
|
||||
PrepareTransition::Continue(new_state, msg) => {
|
||||
outbound.push(msg.get_encoded().unwrap());
|
||||
*state = new_state
|
||||
}
|
||||
PrepareTransition::Finish(out_share) => {
|
||||
out_shares.push(out_share);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if outbound.len() == vdaf.num_aggregators() {
|
||||
// Another round is required before output shares are computed.
|
||||
inbound = vdaf
|
||||
.prepare_shares_to_prepare_message(
|
||||
agg_param,
|
||||
outbound.iter().map(|encoded| {
|
||||
V::PrepareShare::get_decoded_with_param(&states[0], encoded)
|
||||
.expect("failed to decode prep share")
|
||||
}),
|
||||
)?
|
||||
.get_encoded()
|
||||
.unwrap();
|
||||
} else if outbound.is_empty() {
|
||||
// Each Aggregator recovered an output share.
|
||||
break;
|
||||
} else {
|
||||
panic!("Aggregators did not finish the prepare phase at the same time");
|
||||
}
|
||||
}
|
||||
|
||||
if outbound.len() == vdaf.num_aggregators() {
|
||||
// Another round is required before output shares are computed.
|
||||
inbound = vdaf
|
||||
.prepare_shares_to_prepare_message(
|
||||
agg_param,
|
||||
outbound.iter().map(|encoded| {
|
||||
V::PrepareShare::get_decoded_with_param(&states[0], encoded)
|
||||
.expect("failed to decode prep share")
|
||||
}),
|
||||
)?
|
||||
.get_encoded();
|
||||
} else if outbound.is_empty() {
|
||||
// Each Aggregator recovered an output share.
|
||||
break;
|
||||
} else {
|
||||
panic!("Aggregators did not finish the prepare phase at the same time");
|
||||
}
|
||||
Ok(out_shares)
|
||||
}
|
||||
|
||||
Ok(out_shares)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -663,20 +662,17 @@ where
|
|||
for<'a> T: ParameterizedDecode<(&'a V, &'a V::AggregationParam)>,
|
||||
{
|
||||
// Generate an arbitrary vector of field elements.
|
||||
let g = F::one() + F::one();
|
||||
let vec: Vec<F> = itertools::iterate(F::one(), |&v| g * v)
|
||||
.take(length)
|
||||
.collect();
|
||||
let vec: Vec<F> = crate::field::random_vector(length).unwrap();
|
||||
|
||||
// Serialize the field element vector into a vector of bytes.
|
||||
let mut bytes = Vec::with_capacity(vec.len() * F::ENCODED_SIZE);
|
||||
encode_fieldvec(&vec, &mut bytes);
|
||||
encode_fieldvec(&vec, &mut bytes).unwrap();
|
||||
|
||||
// Deserialize the type of interest from those bytes.
|
||||
let value = T::get_decoded_with_param(&(vdaf, agg_param), &bytes).unwrap();
|
||||
|
||||
// Round-trip the value back to a vector of bytes.
|
||||
let encoded = value.get_encoded();
|
||||
let encoded = value.get_encoded().unwrap();
|
||||
|
||||
assert_eq!(encoded, bytes);
|
||||
}
|
||||
|
@ -741,6 +737,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub mod dummy;
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[cfg_attr(
|
||||
|
@ -748,10 +745,14 @@ pub mod dummy;
|
|||
doc(cfg(all(feature = "crypto-dependencies", feature = "experimental")))
|
||||
)]
|
||||
pub mod poplar1;
|
||||
#[cfg(feature = "prio2")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "prio2")))]
|
||||
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(all(feature = "crypto-dependencies", feature = "experimental")))
|
||||
)]
|
||||
pub mod prio2;
|
||||
pub mod prio3;
|
||||
#[cfg(test)]
|
||||
mod prio3_test;
|
||||
#[cfg(any(test, feature = "test-util"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub mod prio3_test;
|
||||
pub mod xof;
|
||||
|
|
|
@ -12,6 +12,9 @@ use crate::{
|
|||
use rand::random;
|
||||
use std::{fmt::Debug, io::Cursor, sync::Arc};
|
||||
|
||||
/// The Dummy VDAF does summation modulus 256 so we can predict aggregation results.
|
||||
const MODULUS: u64 = u8::MAX as u64 + 1;
|
||||
|
||||
type ArcPrepInitFn =
|
||||
Arc<dyn Fn(&AggregationParam) -> Result<(), VdafError> + 'static + Send + Sync>;
|
||||
type ArcPrepStepFn = Arc<
|
||||
|
@ -49,7 +52,9 @@ impl Vdaf {
|
|||
move |state| -> Result<PrepareTransition<Self, 0, 16>, VdafError> {
|
||||
let new_round = state.current_round + 1;
|
||||
if new_round == rounds {
|
||||
Ok(PrepareTransition::Finish(OutputShare(state.input_share)))
|
||||
Ok(PrepareTransition::Finish(OutputShare(u64::from(
|
||||
state.input_share,
|
||||
))))
|
||||
} else {
|
||||
Ok(PrepareTransition::Continue(
|
||||
PrepareState {
|
||||
|
@ -76,7 +81,7 @@ impl Vdaf {
|
|||
self
|
||||
}
|
||||
|
||||
/// Provide an alternate implementation of [`vdaf::Aggregator::prepare_step`].
|
||||
/// Provide an alternate implementation of [`vdaf::Aggregator::prepare_next`].
|
||||
pub fn with_prep_step_fn<
|
||||
F: Fn(&PrepareState) -> Result<PrepareTransition<Self, 0, 16>, VdafError>,
|
||||
>(
|
||||
|
@ -98,16 +103,18 @@ impl Default for Vdaf {
|
|||
}
|
||||
|
||||
impl vdaf::Vdaf for Vdaf {
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
|
||||
type Measurement = u8;
|
||||
type AggregateResult = u8;
|
||||
type AggregateResult = u64;
|
||||
type AggregationParam = AggregationParam;
|
||||
type PublicShare = ();
|
||||
type InputShare = InputShare;
|
||||
type OutputShare = OutputShare;
|
||||
type AggregateShare = AggregateShare;
|
||||
|
||||
fn algorithm_id(&self) -> u32 {
|
||||
0xFFFF0000
|
||||
}
|
||||
|
||||
fn num_aggregators(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
@ -155,7 +162,7 @@ impl vdaf::Aggregator<0, 16> for Vdaf {
|
|||
|
||||
fn aggregate<M: IntoIterator<Item = Self::OutputShare>>(
|
||||
&self,
|
||||
_: &Self::AggregationParam,
|
||||
_aggregation_param: &Self::AggregationParam,
|
||||
output_shares: M,
|
||||
) -> Result<Self::AggregateShare, VdafError> {
|
||||
let mut aggregate_share = AggregateShare(0);
|
||||
|
@ -184,12 +191,28 @@ impl vdaf::Client<16> for Vdaf {
|
|||
}
|
||||
}
|
||||
|
||||
impl vdaf::Collector for Vdaf {
|
||||
fn unshard<M: IntoIterator<Item = Self::AggregateShare>>(
|
||||
&self,
|
||||
aggregation_param: &Self::AggregationParam,
|
||||
agg_shares: M,
|
||||
_num_measurements: usize,
|
||||
) -> Result<Self::AggregateResult, VdafError> {
|
||||
Ok(agg_shares
|
||||
.into_iter()
|
||||
.fold(0, |acc, share| (acc + share.0) % MODULUS)
|
||||
// Sum in the aggregation parameter so that collections over the same measurements with
|
||||
// varying parameters will yield predictable but distinct results.
|
||||
+ u64::from(aggregation_param.0))
|
||||
}
|
||||
}
|
||||
|
||||
/// A dummy input share.
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct InputShare(pub u8);
|
||||
|
||||
impl Encode for InputShare {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
|
@ -209,7 +232,7 @@ impl Decode for InputShare {
|
|||
pub struct AggregationParam(pub u8);
|
||||
|
||||
impl Encode for AggregationParam {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
|
@ -226,17 +249,17 @@ impl Decode for AggregationParam {
|
|||
|
||||
/// Dummy output share.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct OutputShare(pub u8);
|
||||
pub struct OutputShare(pub u64);
|
||||
|
||||
impl Decode for OutputShare {
|
||||
fn decode(bytes: &mut Cursor<&[u8]>) -> Result<Self, CodecError> {
|
||||
Ok(Self(u8::decode(bytes)?))
|
||||
Ok(Self(u64::decode(bytes)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for OutputShare {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.0.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -252,9 +275,9 @@ pub struct PrepareState {
|
|||
}
|
||||
|
||||
impl Encode for PrepareState {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.input_share.encode(bytes);
|
||||
self.current_round.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.input_share.encode(bytes)?;
|
||||
self.current_round.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -282,31 +305,30 @@ impl Aggregatable for AggregateShare {
|
|||
type OutputShare = OutputShare;
|
||||
|
||||
fn merge(&mut self, other: &Self) -> Result<(), VdafError> {
|
||||
self.0 += other.0;
|
||||
self.0 = (self.0 + other.0) % MODULUS;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn accumulate(&mut self, out_share: &Self::OutputShare) -> Result<(), VdafError> {
|
||||
self.0 += u64::from(out_share.0);
|
||||
self.0 = (self.0 + out_share.0) % MODULUS;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OutputShare> for AggregateShare {
|
||||
fn from(out_share: OutputShare) -> Self {
|
||||
Self(u64::from(out_share.0))
|
||||
Self(out_share.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for AggregateShare {
|
||||
fn decode(bytes: &mut Cursor<&[u8]>) -> Result<Self, CodecError> {
|
||||
let val = u64::decode(bytes)?;
|
||||
Ok(Self(val))
|
||||
Ok(Self(u64::decode(bytes)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for AggregateShare {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
|
@ -314,3 +336,86 @@ impl Encode for AggregateShare {
|
|||
self.0.encoded_len()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the aggregate result that the dummy VDAF would compute over the provided measurements,
|
||||
/// for the provided aggregation parameter.
|
||||
pub fn expected_aggregate_result<M>(aggregation_parameter: u8, measurements: M) -> u64
|
||||
where
|
||||
M: IntoIterator<Item = u8>,
|
||||
{
|
||||
(measurements.into_iter().map(u64::from).sum::<u64>()) % MODULUS
|
||||
+ u64::from(aggregation_parameter)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::vdaf::{test_utils::run_vdaf_sharded, Client};
|
||||
use rand::prelude::*;
|
||||
|
||||
fn run_test(rounds: u32, aggregation_parameter: u8) {
|
||||
let vdaf = Vdaf::new(rounds);
|
||||
let mut verify_key = [0; 0];
|
||||
thread_rng().fill(&mut verify_key[..]);
|
||||
let measurements = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
|
||||
|
||||
let mut sharded_measurements = Vec::new();
|
||||
for measurement in measurements {
|
||||
let nonce = thread_rng().gen();
|
||||
let (public_share, input_shares) = vdaf.shard(&measurement, &nonce).unwrap();
|
||||
|
||||
sharded_measurements.push((public_share, nonce, input_shares));
|
||||
}
|
||||
|
||||
let result = run_vdaf_sharded(
|
||||
&vdaf,
|
||||
&AggregationParam(aggregation_parameter),
|
||||
sharded_measurements.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
result,
|
||||
expected_aggregate_result(aggregation_parameter, measurements)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_round_agg_param_10() {
|
||||
run_test(1, 10)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_round_agg_param_20() {
|
||||
run_test(1, 20)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_round_agg_param_32() {
|
||||
run_test(1, 32)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_round_agg_param_u8_max() {
|
||||
run_test(1, u8::MAX)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_round_agg_param_10() {
|
||||
run_test(2, 10)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_round_agg_param_20() {
|
||||
run_test(2, 20)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_round_agg_param_32() {
|
||||
run_test(2, 32)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_round_agg_param_u8_max() {
|
||||
run_test(2, u8::MAX)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! Implementation of Poplar1 as specified in [[draft-irtf-cfrg-vdaf-07]].
|
||||
//! Implementation of Poplar1 as specified in [[draft-irtf-cfrg-vdaf-08]].
|
||||
//!
|
||||
//! [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
//! [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
|
||||
use crate::{
|
||||
codec::{CodecError, Decode, Encode, ParameterizedDecode},
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||
idpf::{Idpf, IdpfInput, IdpfOutputShare, IdpfPublicShare, IdpfValue, RingBufferCache},
|
||||
prng::Prng,
|
||||
vdaf::{
|
||||
xof::{Seed, Xof, XofShake128},
|
||||
xof::{Seed, Xof, XofTurboShake128},
|
||||
Aggregatable, Aggregator, Client, Collector, PrepareTransition, Vdaf, VdafError,
|
||||
},
|
||||
};
|
||||
|
@ -34,9 +34,9 @@ const DST_VERIFY_RANDOMNESS: u16 = 4;
|
|||
|
||||
impl<P, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
||||
/// Create an instance of [`Poplar1`]. The caller provides the bit length of each
|
||||
/// measurement (`BITS` as defined in the [[draft-irtf-cfrg-vdaf-07]]).
|
||||
/// measurement (`BITS` as defined in [[draft-irtf-cfrg-vdaf-08]]).
|
||||
///
|
||||
/// [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
/// [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
pub fn new(bits: usize) -> Self {
|
||||
Self {
|
||||
bits,
|
||||
|
@ -45,12 +45,12 @@ impl<P, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Poplar1<XofShake128, 16> {
|
||||
/// Create an instance of [`Poplar1`] using [`XofShake128`]. The caller provides the bit length of
|
||||
/// each measurement (`BITS` as defined in the [[draft-irtf-cfrg-vdaf-07]]).
|
||||
impl Poplar1<XofTurboShake128, 16> {
|
||||
/// Create an instance of [`Poplar1`] using [`XofTurboShake128`]. The caller provides the bit length of
|
||||
/// each measurement (`BITS` as defined in [[draft-irtf-cfrg-vdaf-08]]).
|
||||
///
|
||||
/// [draft-irtf-cfrg-vdaf-07]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/07/
|
||||
pub fn new_shake128(bits: usize) -> Self {
|
||||
/// [draft-irtf-cfrg-vdaf-08]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/08/
|
||||
pub fn new_turboshake128(bits: usize) -> Self {
|
||||
Poplar1::new(bits)
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ pub struct Poplar1<P, const SEED_SIZE: usize> {
|
|||
impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
||||
/// Construct a `Prng` with the given seed and info-string suffix.
|
||||
fn init_prng<I, B, F>(
|
||||
&self,
|
||||
seed: &[u8; SEED_SIZE],
|
||||
usage: u16,
|
||||
binder_chunks: I,
|
||||
|
@ -75,7 +76,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
P: Xof<SEED_SIZE>,
|
||||
F: FieldElement,
|
||||
{
|
||||
let mut xof = P::init(seed, &Self::domain_separation_tag(usage));
|
||||
let mut xof = P::init(seed, &self.domain_separation_tag(usage));
|
||||
for binder_chunk in binder_chunks.into_iter() {
|
||||
xof.update(binder_chunk.as_ref());
|
||||
}
|
||||
|
@ -156,15 +157,15 @@ impl<const SEED_SIZE: usize> ConstantTimeEq for Poplar1InputShare<SEED_SIZE> {
|
|||
}
|
||||
|
||||
impl<const SEED_SIZE: usize> Encode for Poplar1InputShare<SEED_SIZE> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.idpf_key.encode(bytes);
|
||||
self.corr_seed.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.idpf_key.encode(bytes)?;
|
||||
self.corr_seed.encode(bytes)?;
|
||||
for corr in self.corr_inner.iter() {
|
||||
corr[0].encode(bytes);
|
||||
corr[1].encode(bytes);
|
||||
corr[0].encode(bytes)?;
|
||||
corr[1].encode(bytes)?;
|
||||
}
|
||||
self.corr_leaf[0].encode(bytes);
|
||||
self.corr_leaf[1].encode(bytes);
|
||||
self.corr_leaf[0].encode(bytes)?;
|
||||
self.corr_leaf[1].encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -219,7 +220,7 @@ impl ConstantTimeEq for Poplar1PrepareState {
|
|||
}
|
||||
|
||||
impl Encode for Poplar1PrepareState {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
|
@ -268,15 +269,15 @@ impl ConstantTimeEq for PrepareStateVariant {
|
|||
}
|
||||
|
||||
impl Encode for PrepareStateVariant {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
match self {
|
||||
PrepareStateVariant::Inner(prep_state) => {
|
||||
0u8.encode(bytes);
|
||||
prep_state.encode(bytes);
|
||||
0u8.encode(bytes)?;
|
||||
prep_state.encode(bytes)
|
||||
}
|
||||
PrepareStateVariant::Leaf(prep_state) => {
|
||||
1u8.encode(bytes);
|
||||
prep_state.encode(bytes);
|
||||
1u8.encode(bytes)?;
|
||||
prep_state.encode(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,16 +343,17 @@ impl<F> Debug for PrepareState<F> {
|
|||
}
|
||||
|
||||
impl<F: FieldElement> Encode for PrepareState<F> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.sketch.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.sketch.encode(bytes)?;
|
||||
// `expect` safety: output_share's length is the same as the number of prefixes; the number
|
||||
// of prefixes is capped at 2^32-1.
|
||||
u32::try_from(self.output_share.len())
|
||||
.expect("Couldn't convert output_share length to u32")
|
||||
.encode(bytes);
|
||||
.encode(bytes)?;
|
||||
for elem in &self.output_share {
|
||||
elem.encode(bytes);
|
||||
elem.encode(bytes)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -430,14 +432,14 @@ impl<F: ConstantTimeEq> ConstantTimeEq for SketchState<F> {
|
|||
}
|
||||
|
||||
impl<F: FieldElement> Encode for SketchState<F> {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
match self {
|
||||
SketchState::RoundOne {
|
||||
A_share, B_share, ..
|
||||
} => {
|
||||
0u8.encode(bytes);
|
||||
A_share.encode(bytes);
|
||||
B_share.encode(bytes);
|
||||
0u8.encode(bytes)?;
|
||||
A_share.encode(bytes)?;
|
||||
B_share.encode(bytes)
|
||||
}
|
||||
SketchState::RoundTwo => 1u8.encode(bytes),
|
||||
}
|
||||
|
@ -519,19 +521,19 @@ enum PrepareMessageVariant {
|
|||
}
|
||||
|
||||
impl Encode for Poplar1PrepareMessage {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
match self.0 {
|
||||
PrepareMessageVariant::SketchInner(vec) => {
|
||||
vec[0].encode(bytes);
|
||||
vec[1].encode(bytes);
|
||||
vec[2].encode(bytes);
|
||||
vec[0].encode(bytes)?;
|
||||
vec[1].encode(bytes)?;
|
||||
vec[2].encode(bytes)
|
||||
}
|
||||
PrepareMessageVariant::SketchLeaf(vec) => {
|
||||
vec[0].encode(bytes);
|
||||
vec[1].encode(bytes);
|
||||
vec[2].encode(bytes);
|
||||
vec[0].encode(bytes)?;
|
||||
vec[1].encode(bytes)?;
|
||||
vec[2].encode(bytes)
|
||||
}
|
||||
PrepareMessageVariant::Done => (),
|
||||
PrepareMessageVariant::Done => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,17 +616,19 @@ impl ConstantTimeEq for Poplar1FieldVec {
|
|||
}
|
||||
|
||||
impl Encode for Poplar1FieldVec {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
match self {
|
||||
Self::Inner(ref data) => {
|
||||
for elem in data {
|
||||
elem.encode(bytes);
|
||||
elem.encode(bytes)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Self::Leaf(ref data) => {
|
||||
for elem in data {
|
||||
elem.encode(bytes);
|
||||
elem.encode(bytes)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -769,11 +773,11 @@ impl Poplar1AggregationParam {
|
|||
}
|
||||
|
||||
impl Encode for Poplar1AggregationParam {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
// Okay to unwrap because `try_from_prefixes()` checks this conversion succeeds.
|
||||
let prefix_count = u32::try_from(self.prefixes.len()).unwrap();
|
||||
self.level.encode(bytes);
|
||||
prefix_count.encode(bytes);
|
||||
self.level.encode(bytes)?;
|
||||
prefix_count.encode(bytes)?;
|
||||
|
||||
// The encoding of the prefixes is defined by treating the IDPF indices as integers,
|
||||
// shifting and ORing them together, and encoding the resulting arbitrary precision integer
|
||||
|
@ -799,6 +803,7 @@ impl Encode for Poplar1AggregationParam {
|
|||
let mut packed = packed.into_vec();
|
||||
packed.reverse();
|
||||
bytes.append(&mut packed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -839,7 +844,6 @@ impl Decode for Poplar1AggregationParam {
|
|||
}
|
||||
|
||||
impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Vdaf for Poplar1<P, SEED_SIZE> {
|
||||
const ID: u32 = 0x00001000;
|
||||
type Measurement = IdpfInput;
|
||||
type AggregateResult = Vec<u64>;
|
||||
type AggregationParam = Poplar1AggregationParam;
|
||||
|
@ -848,6 +852,10 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Vdaf for Poplar1<P, SEED_SIZE> {
|
|||
type OutputShare = Poplar1FieldVec;
|
||||
type AggregateShare = Poplar1FieldVec;
|
||||
|
||||
fn algorithm_id(&self) -> u32 {
|
||||
0x00001000
|
||||
}
|
||||
|
||||
fn num_aggregators(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
@ -870,7 +878,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
|
||||
// Generate the authenticator for each inner level of the IDPF tree.
|
||||
let mut prng =
|
||||
Self::init_prng::<_, _, Field64>(&poplar_random[2], DST_SHARD_RANDOMNESS, [&[]]);
|
||||
self.init_prng::<_, _, Field64>(&poplar_random[2], DST_SHARD_RANDOMNESS, [nonce]);
|
||||
let auth_inner: Vec<Field64> = (0..self.bits - 1).map(|_| prng.get()).collect();
|
||||
|
||||
// Generate the authenticator for the last level of the IDPF tree (i.e., the leaves).
|
||||
|
@ -900,12 +908,12 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
let corr_seed_0 = &poplar_random[0];
|
||||
let corr_seed_1 = &poplar_random[1];
|
||||
let mut prng = prng.into_new_field::<Field64>();
|
||||
let mut corr_prng_0 = Self::init_prng::<_, _, Field64>(
|
||||
let mut corr_prng_0 = self.init_prng::<_, _, Field64>(
|
||||
corr_seed_0,
|
||||
DST_CORR_INNER,
|
||||
[[0].as_slice(), nonce.as_slice()],
|
||||
);
|
||||
let mut corr_prng_1 = Self::init_prng::<_, _, Field64>(
|
||||
let mut corr_prng_1 = self.init_prng::<_, _, Field64>(
|
||||
corr_seed_1,
|
||||
DST_CORR_INNER,
|
||||
[[1].as_slice(), nonce.as_slice()],
|
||||
|
@ -921,12 +929,12 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
|
||||
// Generate the correlated randomness for the leaf nodes.
|
||||
let mut prng = prng.into_new_field::<Field255>();
|
||||
let mut corr_prng_0 = Self::init_prng::<_, _, Field255>(
|
||||
let mut corr_prng_0 = self.init_prng::<_, _, Field255>(
|
||||
corr_seed_0,
|
||||
DST_CORR_LEAF,
|
||||
[[0].as_slice(), nonce.as_slice()],
|
||||
);
|
||||
let mut corr_prng_1 = Self::init_prng::<_, _, Field255>(
|
||||
let mut corr_prng_1 = self.init_prng::<_, _, Field255>(
|
||||
corr_seed_1,
|
||||
DST_CORR_LEAF,
|
||||
[[1].as_slice(), nonce.as_slice()],
|
||||
|
@ -952,6 +960,60 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
|
|||
],
|
||||
))
|
||||
}
|
||||
|
||||
/// Evaluate the IDPF at the given prefixes and compute the Aggregator's share of the sketch.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn eval_and_sketch<F>(
|
||||
&self,
|
||||
verify_key: &[u8; SEED_SIZE],
|
||||
agg_id: usize,
|
||||
nonce: &[u8; 16],
|
||||
agg_param: &Poplar1AggregationParam,
|
||||
public_share: &Poplar1PublicShare,
|
||||
idpf_key: &Seed<16>,
|
||||
corr_prng: &mut Prng<F, P::SeedStream>,
|
||||
) -> Result<(Vec<F>, Vec<F>), VdafError>
|
||||
where
|
||||
P: Xof<SEED_SIZE>,
|
||||
F: FieldElement,
|
||||
Poplar1IdpfValue<F>:
|
||||
From<IdpfOutputShare<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>>,
|
||||
{
|
||||
let mut verify_prng = self.init_prng(
|
||||
verify_key,
|
||||
DST_VERIFY_RANDOMNESS,
|
||||
[nonce.as_slice(), agg_param.level.to_be_bytes().as_slice()],
|
||||
);
|
||||
|
||||
let mut out_share = Vec::with_capacity(agg_param.prefixes.len());
|
||||
let mut sketch_share = vec![
|
||||
corr_prng.get(), // a_share
|
||||
corr_prng.get(), // b_share
|
||||
corr_prng.get(), // c_share
|
||||
];
|
||||
|
||||
let mut idpf_eval_cache = RingBufferCache::new(agg_param.prefixes.len());
|
||||
let idpf = Idpf::<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>::new((), ());
|
||||
for prefix in agg_param.prefixes.iter() {
|
||||
let share = Poplar1IdpfValue::<F>::from(idpf.eval(
|
||||
agg_id,
|
||||
public_share,
|
||||
idpf_key,
|
||||
prefix,
|
||||
nonce,
|
||||
&mut idpf_eval_cache,
|
||||
)?);
|
||||
|
||||
let r = verify_prng.get();
|
||||
let checked_data_share = share.0[0] * r;
|
||||
sketch_share[0] += checked_data_share;
|
||||
sketch_share[1] += checked_data_share * r;
|
||||
sketch_share[2] += share.0[1] * r;
|
||||
out_share.push(share.0[0]);
|
||||
}
|
||||
|
||||
Ok((out_share, sketch_share))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Client<16> for Poplar1<P, SEED_SIZE> {
|
||||
|
@ -1000,7 +1062,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Aggregator<SEED_SIZE, 16>
|
|||
};
|
||||
|
||||
if usize::from(agg_param.level) < self.bits - 1 {
|
||||
let mut corr_prng = Self::init_prng::<_, _, Field64>(
|
||||
let mut corr_prng = self.init_prng::<_, _, Field64>(
|
||||
input_share.corr_seed.as_ref(),
|
||||
DST_CORR_INNER,
|
||||
[[agg_id as u8].as_slice(), nonce.as_slice()],
|
||||
|
@ -1011,7 +1073,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Aggregator<SEED_SIZE, 16>
|
|||
corr_prng.get();
|
||||
}
|
||||
|
||||
let (output_share, sketch_share) = eval_and_sketch::<P, Field64, SEED_SIZE>(
|
||||
let (output_share, sketch_share) = self.eval_and_sketch::<Field64>(
|
||||
verify_key,
|
||||
agg_id,
|
||||
nonce,
|
||||
|
@ -1033,13 +1095,13 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Aggregator<SEED_SIZE, 16>
|
|||
Poplar1FieldVec::Inner(sketch_share),
|
||||
))
|
||||
} else {
|
||||
let corr_prng = Self::init_prng::<_, _, Field255>(
|
||||
let corr_prng = self.init_prng::<_, _, Field255>(
|
||||
input_share.corr_seed.as_ref(),
|
||||
DST_CORR_LEAF,
|
||||
[[agg_id as u8].as_slice(), nonce.as_slice()],
|
||||
);
|
||||
|
||||
let (output_share, sketch_share) = eval_and_sketch::<P, Field255, SEED_SIZE>(
|
||||
let (output_share, sketch_share) = self.eval_and_sketch::<Field255>(
|
||||
verify_key,
|
||||
agg_id,
|
||||
nonce,
|
||||
|
@ -1257,59 +1319,6 @@ fn compute_next_corr_shares<F: FieldElement + From<u64>, S: RngCore>(
|
|||
(corr_0, corr_1)
|
||||
}
|
||||
|
||||
/// Evaluate the IDPF at the given prefixes and compute the Aggregator's share of the sketch.
|
||||
fn eval_and_sketch<P, F, const SEED_SIZE: usize>(
|
||||
verify_key: &[u8; SEED_SIZE],
|
||||
agg_id: usize,
|
||||
nonce: &[u8; 16],
|
||||
agg_param: &Poplar1AggregationParam,
|
||||
public_share: &Poplar1PublicShare,
|
||||
idpf_key: &Seed<16>,
|
||||
corr_prng: &mut Prng<F, P::SeedStream>,
|
||||
) -> Result<(Vec<F>, Vec<F>), VdafError>
|
||||
where
|
||||
P: Xof<SEED_SIZE>,
|
||||
F: FieldElement,
|
||||
Poplar1IdpfValue<F>:
|
||||
From<IdpfOutputShare<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>>,
|
||||
{
|
||||
// TODO(cjpatton) spec: Consider not encoding the prefixes here.
|
||||
let mut verify_prng = Poplar1::<P, SEED_SIZE>::init_prng(
|
||||
verify_key,
|
||||
DST_VERIFY_RANDOMNESS,
|
||||
[nonce.as_slice(), agg_param.level.to_be_bytes().as_slice()],
|
||||
);
|
||||
|
||||
let mut out_share = Vec::with_capacity(agg_param.prefixes.len());
|
||||
let mut sketch_share = vec![
|
||||
corr_prng.get(), // a_share
|
||||
corr_prng.get(), // b_share
|
||||
corr_prng.get(), // c_share
|
||||
];
|
||||
|
||||
let mut idpf_eval_cache = RingBufferCache::new(agg_param.prefixes.len());
|
||||
let idpf = Idpf::<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>::new((), ());
|
||||
for prefix in agg_param.prefixes.iter() {
|
||||
let share = Poplar1IdpfValue::<F>::from(idpf.eval(
|
||||
agg_id,
|
||||
public_share,
|
||||
idpf_key,
|
||||
prefix,
|
||||
nonce,
|
||||
&mut idpf_eval_cache,
|
||||
)?);
|
||||
|
||||
let r = verify_prng.get();
|
||||
let checked_data_share = share.0[0] * r;
|
||||
sketch_share[0] += checked_data_share;
|
||||
sketch_share[1] += checked_data_share * r;
|
||||
sketch_share[2] += share.0[1] * r;
|
||||
out_share.push(share.0[0]);
|
||||
}
|
||||
|
||||
Ok((out_share, sketch_share))
|
||||
}
|
||||
|
||||
/// Compute the Aggregator's share of the sketch verifier. The shares should sum to zero.
|
||||
#[allow(non_snake_case)]
|
||||
fn finish_sketch<F: FieldElement>(
|
||||
|
@ -1447,9 +1456,9 @@ impl<F> Encode for Poplar1IdpfValue<F>
|
|||
where
|
||||
F: FieldElement,
|
||||
{
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.0[0].encode(bytes);
|
||||
self.0[1].encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0[0].encode(bytes)?;
|
||||
self.0[1].encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -1491,7 +1500,7 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::vdaf::{equality_comparison_test, run_vdaf_prepare};
|
||||
use crate::vdaf::{equality_comparison_test, test_utils::run_vdaf_prepare};
|
||||
use assert_matches::assert_matches;
|
||||
use rand::prelude::*;
|
||||
use serde::Deserialize;
|
||||
|
@ -1628,7 +1637,7 @@ mod tests {
|
|||
#[test]
|
||||
fn shard_prepare() {
|
||||
let mut rng = thread_rng();
|
||||
let vdaf = Poplar1::new_shake128(64);
|
||||
let vdaf = Poplar1::new_turboshake128(64);
|
||||
let verify_key = rng.gen();
|
||||
let input = IdpfInput::from_bytes(b"12341324");
|
||||
let nonce = rng.gen();
|
||||
|
@ -1672,7 +1681,7 @@ mod tests {
|
|||
fn heavy_hitters() {
|
||||
let mut rng = thread_rng();
|
||||
let verify_key = rng.gen();
|
||||
let vdaf = Poplar1::new_shake128(8);
|
||||
let vdaf = Poplar1::new_turboshake128(8);
|
||||
|
||||
run_heavy_hitters(
|
||||
&vdaf,
|
||||
|
@ -1699,7 +1708,7 @@ mod tests {
|
|||
corr_leaf: [Field255::one(), <Field255 as FieldElement>::zero()],
|
||||
};
|
||||
assert_eq!(
|
||||
input_share.get_encoded().len(),
|
||||
input_share.get_encoded().unwrap().len(),
|
||||
input_share.encoded_len().unwrap()
|
||||
);
|
||||
|
||||
|
@ -1710,7 +1719,7 @@ mod tests {
|
|||
Field64::one(),
|
||||
]));
|
||||
assert_eq!(
|
||||
prep_msg.get_encoded().len(),
|
||||
prep_msg.get_encoded().unwrap().len(),
|
||||
prep_msg.encoded_len().unwrap()
|
||||
);
|
||||
let prep_msg = Poplar1PrepareMessage(PrepareMessageVariant::SketchLeaf([
|
||||
|
@ -1719,24 +1728,24 @@ mod tests {
|
|||
Field255::one(),
|
||||
]));
|
||||
assert_eq!(
|
||||
prep_msg.get_encoded().len(),
|
||||
prep_msg.get_encoded().unwrap().len(),
|
||||
prep_msg.encoded_len().unwrap()
|
||||
);
|
||||
let prep_msg = Poplar1PrepareMessage(PrepareMessageVariant::Done);
|
||||
assert_eq!(
|
||||
prep_msg.get_encoded().len(),
|
||||
prep_msg.get_encoded().unwrap().len(),
|
||||
prep_msg.encoded_len().unwrap()
|
||||
);
|
||||
|
||||
// Field vector variants.
|
||||
let field_vec = Poplar1FieldVec::Inner(vec![Field64::one(); 23]);
|
||||
assert_eq!(
|
||||
field_vec.get_encoded().len(),
|
||||
field_vec.get_encoded().unwrap().len(),
|
||||
field_vec.encoded_len().unwrap()
|
||||
);
|
||||
let field_vec = Poplar1FieldVec::Leaf(vec![Field255::one(); 23]);
|
||||
assert_eq!(
|
||||
field_vec.get_encoded().len(),
|
||||
field_vec.get_encoded().unwrap().len(),
|
||||
field_vec.encoded_len().unwrap()
|
||||
);
|
||||
|
||||
|
@ -1747,7 +1756,7 @@ mod tests {
|
|||
]))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
agg_param.get_encoded().len(),
|
||||
agg_param.get_encoded().unwrap().len(),
|
||||
agg_param.encoded_len().unwrap()
|
||||
);
|
||||
let agg_param = Poplar1AggregationParam::try_from_prefixes(Vec::from([
|
||||
|
@ -1756,14 +1765,14 @@ mod tests {
|
|||
]))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
agg_param.get_encoded().len(),
|
||||
agg_param.get_encoded().unwrap().len(),
|
||||
agg_param.encoded_len().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip_prepare_state() {
|
||||
let vdaf = Poplar1::new_shake128(1);
|
||||
let vdaf = Poplar1::new_turboshake128(1);
|
||||
for (agg_id, prep_state) in [
|
||||
(
|
||||
0,
|
||||
|
@ -1862,7 +1871,7 @@ mod tests {
|
|||
})),
|
||||
),
|
||||
] {
|
||||
let encoded_prep_state = prep_state.get_encoded();
|
||||
let encoded_prep_state = prep_state.get_encoded().unwrap();
|
||||
assert_eq!(prep_state.encoded_len(), Some(encoded_prep_state.len()));
|
||||
let decoded_prep_state =
|
||||
Poplar1PrepareState::get_decoded_with_param(&(&vdaf, agg_id), &encoded_prep_state)
|
||||
|
@ -1947,7 +1956,7 @@ mod tests {
|
|||
),
|
||||
] {
|
||||
let agg_param = Poplar1AggregationParam::try_from_prefixes(prefixes).unwrap();
|
||||
let encoded = agg_param.get_encoded();
|
||||
let encoded = agg_param.get_encoded().unwrap();
|
||||
assert_eq!(encoded, reference_encoding);
|
||||
let decoded = Poplar1AggregationParam::get_decoded(reference_encoding).unwrap();
|
||||
assert_eq!(decoded, agg_param);
|
||||
|
@ -2037,7 +2046,7 @@ mod tests {
|
|||
}
|
||||
|
||||
// Shard measurement.
|
||||
let poplar = Poplar1::new_shake128(test_vector.bits);
|
||||
let poplar = Poplar1::new_turboshake128(test_vector.bits);
|
||||
let (public_share, input_shares) = poplar
|
||||
.shard_with_random(&measurement, &nonce, &idpf_random, &poplar_random)
|
||||
.unwrap();
|
||||
|
@ -2118,14 +2127,17 @@ mod tests {
|
|||
Poplar1PublicShare::get_decoded_with_param(&poplar, prep.public_share.as_ref())
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(&public_share.get_encoded(), prep.public_share.as_ref());
|
||||
assert_eq!(
|
||||
&public_share.get_encoded().unwrap(),
|
||||
prep.public_share.as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
input_shares[0],
|
||||
Poplar1InputShare::get_decoded_with_param(&(&poplar, 0), prep.input_shares[0].as_ref())
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&input_shares[0].get_encoded(),
|
||||
&input_shares[0].get_encoded().unwrap(),
|
||||
prep.input_shares[0].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2134,7 +2146,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&input_shares[1].get_encoded(),
|
||||
&input_shares[1].get_encoded().unwrap(),
|
||||
prep.input_shares[1].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2146,7 +2158,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&init_prep_share_0.get_encoded(),
|
||||
&init_prep_share_0.get_encoded().unwrap(),
|
||||
prep.prep_shares[0][0].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2158,7 +2170,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&init_prep_share_1.get_encoded(),
|
||||
&init_prep_share_1.get_encoded().unwrap(),
|
||||
prep.prep_shares[0][1].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2169,7 +2181,10 @@ mod tests {
|
|||
)
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(&r1_prep_msg.get_encoded(), prep.prep_messages[0].as_ref());
|
||||
assert_eq!(
|
||||
&r1_prep_msg.get_encoded().unwrap(),
|
||||
prep.prep_messages[0].as_ref()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
r1_prep_share_0,
|
||||
|
@ -2180,7 +2195,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&r1_prep_share_0.get_encoded(),
|
||||
&r1_prep_share_0.get_encoded().unwrap(),
|
||||
prep.prep_shares[1][0].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2192,7 +2207,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&r1_prep_share_1.get_encoded(),
|
||||
&r1_prep_share_1.get_encoded().unwrap(),
|
||||
prep.prep_shares[1][1].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2203,7 +2218,10 @@ mod tests {
|
|||
)
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(&r2_prep_msg.get_encoded(), prep.prep_messages[1].as_ref());
|
||||
assert_eq!(
|
||||
&r2_prep_msg.get_encoded().unwrap(),
|
||||
prep.prep_messages[1].as_ref()
|
||||
);
|
||||
for (out_share, expected_out_share) in [
|
||||
(out_share_0, &prep.out_shares[0]),
|
||||
(out_share_1, &prep.out_shares[1]),
|
||||
|
@ -2212,13 +2230,13 @@ mod tests {
|
|||
Poplar1FieldVec::Inner(vec) => {
|
||||
assert_eq!(vec.len(), expected_out_share.len());
|
||||
for (element, expected) in vec.iter().zip(expected_out_share.iter()) {
|
||||
assert_eq!(&element.get_encoded(), expected.as_ref());
|
||||
assert_eq!(&element.get_encoded().unwrap(), expected.as_ref());
|
||||
}
|
||||
}
|
||||
Poplar1FieldVec::Leaf(vec) => {
|
||||
assert_eq!(vec.len(), expected_out_share.len());
|
||||
for (element, expected) in vec.iter().zip(expected_out_share.iter()) {
|
||||
assert_eq!(&element.get_encoded(), expected.as_ref());
|
||||
assert_eq!(&element.get_encoded().unwrap(), expected.as_ref());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -2233,7 +2251,7 @@ mod tests {
|
|||
);
|
||||
|
||||
assert_eq!(
|
||||
&agg_share_0.get_encoded(),
|
||||
&agg_share_0.get_encoded().unwrap(),
|
||||
test_vector.agg_shares[0].as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -2245,7 +2263,7 @@ mod tests {
|
|||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
&agg_share_1.get_encoded(),
|
||||
&agg_share_1.get_encoded().unwrap(),
|
||||
test_vector.agg_shares[1].as_ref()
|
||||
);
|
||||
assert_eq!(agg_result, test_vector.agg_result);
|
||||
|
@ -2253,22 +2271,22 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_vec_poplar1_0() {
|
||||
check_test_vec(include_str!("test_vec/07/Poplar1_0.json"));
|
||||
check_test_vec(include_str!("test_vec/08/Poplar1_0.json"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_poplar1_1() {
|
||||
check_test_vec(include_str!("test_vec/07/Poplar1_1.json"));
|
||||
check_test_vec(include_str!("test_vec/08/Poplar1_1.json"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_poplar1_2() {
|
||||
check_test_vec(include_str!("test_vec/07/Poplar1_2.json"));
|
||||
check_test_vec(include_str!("test_vec/08/Poplar1_2.json"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_poplar1_3() {
|
||||
check_test_vec(include_str!("test_vec/07/Poplar1_3.json"));
|
||||
check_test_vec(include_str!("test_vec/08/Poplar1_3.json"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -88,8 +88,13 @@ impl Prio2 {
|
|||
)
|
||||
.map_err(|e| VdafError::Uncategorized(e.to_string()))?;
|
||||
|
||||
let truncated_share = match input_share {
|
||||
Share::Leader(data) => Share::Leader(data[..self.input_len].to_vec()),
|
||||
Share::Helper(seed) => Share::Helper(seed.clone()),
|
||||
};
|
||||
|
||||
Ok((
|
||||
Prio2PrepareState(input_share.truncated(self.input_len)),
|
||||
Prio2PrepareState(truncated_share),
|
||||
Prio2PrepareShare(verifier_share),
|
||||
))
|
||||
}
|
||||
|
@ -117,7 +122,6 @@ impl Prio2 {
|
|||
}
|
||||
|
||||
impl Vdaf for Prio2 {
|
||||
const ID: u32 = 0xFFFF0000;
|
||||
type Measurement = Vec<u32>;
|
||||
type AggregateResult = Vec<u32>;
|
||||
type AggregationParam = ();
|
||||
|
@ -126,6 +130,10 @@ impl Vdaf for Prio2 {
|
|||
type OutputShare = OutputShare<FieldPrio2>;
|
||||
type AggregateShare = AggregateShare<FieldPrio2>;
|
||||
|
||||
fn algorithm_id(&self) -> u32 {
|
||||
0xFFFF0000
|
||||
}
|
||||
|
||||
fn num_aggregators(&self) -> usize {
|
||||
// Prio2 can easily be extended to support more than two Aggregators.
|
||||
2
|
||||
|
@ -184,8 +192,8 @@ impl ConstantTimeEq for Prio2PrepareState {
|
|||
}
|
||||
|
||||
impl Encode for Prio2PrepareState {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.0.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -213,10 +221,10 @@ impl<'a> ParameterizedDecode<(&'a Prio2, usize)> for Prio2PrepareState {
|
|||
pub struct Prio2PrepareShare(v2_server::VerificationMessage<FieldPrio2>);
|
||||
|
||||
impl Encode for Prio2PrepareShare {
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
self.0.f_r.encode(bytes);
|
||||
self.0.g_r.encode(bytes);
|
||||
self.0.h_r.encode(bytes);
|
||||
fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> {
|
||||
self.0.f_r.encode(bytes)?;
|
||||
self.0.g_r.encode(bytes)?;
|
||||
self.0.h_r.encode(bytes)
|
||||
}
|
||||
|
||||
fn encoded_len(&self) -> Option<usize> {
|
||||
|
@ -388,7 +396,7 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::vdaf::{
|
||||
equality_comparison_test, fieldvec_roundtrip_test, prio2::test_vector::Priov2TestVector,
|
||||
run_vdaf,
|
||||
test_utils::run_vdaf,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use rand::prelude::*;
|
||||
|
@ -434,7 +442,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let encoded_prepare_state = prepare_state.get_encoded();
|
||||
let encoded_prepare_state = prepare_state.get_encoded().unwrap();
|
||||
let decoded_prepare_state = Prio2PrepareState::get_decoded_with_param(
|
||||
&(&prio2, agg_id),
|
||||
&encoded_prepare_state,
|
||||
|
@ -446,7 +454,7 @@ mod tests {
|
|||
encoded_prepare_state.len()
|
||||
);
|
||||
|
||||
let encoded_prepare_share = prepare_share.get_encoded();
|
||||
let encoded_prepare_share = prepare_share.get_encoded().unwrap();
|
||||
let decoded_prepare_share =
|
||||
Prio2PrepareShare::get_decoded_with_param(&prepare_state, &encoded_prepare_share)
|
||||
.expect("failed to decode prepare share");
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
//! Primitives for the Prio2 client.
|
||||
|
||||
use crate::{
|
||||
field::{FftFriendlyFieldElement, FieldError},
|
||||
codec::CodecError,
|
||||
field::FftFriendlyFieldElement,
|
||||
polynomial::{poly_fft, PolyAuxMemory},
|
||||
prng::{Prng, PrngError},
|
||||
vdaf::{xof::SeedStreamAes128, VdafError},
|
||||
vdaf::{
|
||||
xof::{Seed, SeedStreamAes128},
|
||||
VdafError,
|
||||
},
|
||||
};
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
@ -32,9 +36,9 @@ pub enum SerializeError {
|
|||
/// Emitted by `unpack_proof[_mut]` if the serialized share+proof has the wrong length
|
||||
#[error("serialized input has wrong length")]
|
||||
UnpackInputSizeMismatch,
|
||||
/// Finite field operation error.
|
||||
#[error("finite field operation error")]
|
||||
Field(#[from] FieldError),
|
||||
/// Codec error.
|
||||
#[error(transparent)]
|
||||
Codec(#[from] CodecError),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -63,7 +67,7 @@ impl<F: FftFriendlyFieldElement> ClientMemory<F> {
|
|||
}
|
||||
|
||||
Ok(Self {
|
||||
prng: Prng::new()?,
|
||||
prng: Prng::from_prio2_seed(Seed::<32>::generate()?.as_ref()),
|
||||
points_f: vec![F::zero(); n],
|
||||
points_g: vec![F::zero(); n],
|
||||
evals_f: vec![F::zero(); 2 * n],
|
||||
|
|
|
@ -101,9 +101,13 @@ pub(crate) fn is_valid_share<F: FftFriendlyFieldElement>(
|
|||
#[cfg(test)]
|
||||
mod test_util {
|
||||
use crate::{
|
||||
codec::ParameterizedDecode,
|
||||
field::{merge_vector, FftFriendlyFieldElement},
|
||||
prng::Prng,
|
||||
vdaf::prio2::client::proof_length,
|
||||
vdaf::{
|
||||
prio2::client::{proof_length, SerializeError},
|
||||
Share, ShareDecodingParameter,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{generate_verification_message, is_valid_share, ServerError, VerificationMessage};
|
||||
|
@ -133,17 +137,17 @@ mod test_util {
|
|||
/// Deserialize
|
||||
fn deserialize_share(&self, share: &[u8]) -> Result<Vec<F>, ServerError> {
|
||||
let len = proof_length(self.dimension);
|
||||
Ok(if self.is_first_server {
|
||||
F::byte_slice_into_vec(share)?
|
||||
let decoding_parameter = if self.is_first_server {
|
||||
ShareDecodingParameter::Leader(len)
|
||||
} else {
|
||||
if share.len() != 32 {
|
||||
return Err(ServerError::ShareLength);
|
||||
}
|
||||
|
||||
Prng::from_prio2_seed(&share.try_into().unwrap())
|
||||
.take(len)
|
||||
.collect()
|
||||
})
|
||||
ShareDecodingParameter::Helper
|
||||
};
|
||||
let decoded_share = Share::get_decoded_with_param(&decoding_parameter, share)
|
||||
.map_err(SerializeError::from)?;
|
||||
match decoded_share {
|
||||
Share::Leader(vec) => Ok(vec),
|
||||
Share::Helper(seed) => Ok(Prng::from_prio2_seed(&seed.0).take(len).collect()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate verification message from an encrypted share
|
||||
|
@ -194,14 +198,19 @@ mod test_util {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
codec::Encode,
|
||||
codec::{Encode, ParameterizedDecode},
|
||||
field::{FieldElement, FieldPrio2},
|
||||
prng::Prng,
|
||||
vdaf::{
|
||||
prio2::{client::unpack_proof_mut, server::test_util::Server, Prio2},
|
||||
Client,
|
||||
prio2::{
|
||||
client::{proof_length, unpack_proof_mut},
|
||||
server::test_util::Server,
|
||||
Prio2,
|
||||
},
|
||||
Client, Share, ShareDecodingParameter,
|
||||
},
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use rand::{random, Rng};
|
||||
|
||||
fn secret_share(share: &mut [FieldPrio2]) -> Vec<FieldPrio2> {
|
||||
|
@ -286,10 +295,13 @@ mod tests {
|
|||
|
||||
let vdaf = Prio2::new(dim).unwrap();
|
||||
let (_, shares) = vdaf.shard(&data, &[0; 16]).unwrap();
|
||||
let share1_original = shares[0].get_encoded();
|
||||
let share2 = shares[1].get_encoded();
|
||||
let share1_original = shares[0].get_encoded().unwrap();
|
||||
let share2 = shares[1].get_encoded().unwrap();
|
||||
|
||||
let mut share1_field = FieldPrio2::byte_slice_into_vec(&share1_original).unwrap();
|
||||
let mut share1_field: Vec<FieldPrio2> = assert_matches!(
|
||||
Share::get_decoded_with_param(&ShareDecodingParameter::<32>::Leader(proof_length(dim)), &share1_original),
|
||||
Ok(Share::Leader(vec)) => vec
|
||||
);
|
||||
let unpacked_share1 = unpack_proof_mut(&mut share1_field, dim).unwrap();
|
||||
|
||||
let one = FieldPrio2::from(1);
|
||||
|
@ -304,7 +316,9 @@ mod tests {
|
|||
};
|
||||
|
||||
// reserialize altered share1
|
||||
let share1_modified = FieldPrio2::slice_into_byte_vec(&share1_field);
|
||||
let share1_modified = Share::<FieldPrio2, 32>::Leader(share1_field)
|
||||
.get_encoded()
|
||||
.unwrap();
|
||||
|
||||
let mut prng = Prng::from_prio2_seed(&random());
|
||||
let eval_at = vdaf.choose_eval_at(&mut prng);
|
||||
|
|
|
@ -48,9 +48,16 @@ mod base64 {
|
|||
//! instead of an array of an array of integers when serializing to JSON.
|
||||
//
|
||||
// Thank you, Alice! https://users.rust-lang.org/t/serialize-a-vec-u8-to-json-as-base64/57781/2
|
||||
use crate::field::{FieldElement, FieldPrio2};
|
||||
use crate::{
|
||||
codec::ParameterizedDecode,
|
||||
field::{encode_fieldvec, FieldElement, FieldPrio2},
|
||||
vdaf::{Share, ShareDecodingParameter},
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use base64::{engine::Engine, prelude::BASE64_STANDARD};
|
||||
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::{
|
||||
de::Error as _, ser::Error as _, Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
|
||||
pub fn serialize_bytes<S: Serializer>(v: &[Vec<u8>], s: S) -> Result<S::Ok, S::Error> {
|
||||
let base64_vec = v
|
||||
|
@ -63,21 +70,28 @@ mod base64 {
|
|||
pub fn deserialize_bytes<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<Vec<u8>>, D::Error> {
|
||||
<Vec<String>>::deserialize(d)?
|
||||
.iter()
|
||||
.map(|s| BASE64_STANDARD.decode(s.as_bytes()).map_err(Error::custom))
|
||||
.map(|s| {
|
||||
BASE64_STANDARD
|
||||
.decode(s.as_bytes())
|
||||
.map_err(D::Error::custom)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn serialize_field<S: Serializer>(v: &[FieldPrio2], s: S) -> Result<S::Ok, S::Error> {
|
||||
String::serialize(
|
||||
&BASE64_STANDARD.encode(FieldPrio2::slice_into_byte_vec(v)),
|
||||
s,
|
||||
)
|
||||
let mut bytes = Vec::new();
|
||||
encode_fieldvec(v, &mut bytes).map_err(S::Error::custom)?;
|
||||
String::serialize(&BASE64_STANDARD.encode(&bytes), s)
|
||||
}
|
||||
|
||||
pub fn deserialize_field<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<FieldPrio2>, D::Error> {
|
||||
let bytes = BASE64_STANDARD
|
||||
.decode(String::deserialize(d)?.as_bytes())
|
||||
.map_err(Error::custom)?;
|
||||
FieldPrio2::byte_slice_into_vec(&bytes).map_err(Error::custom)
|
||||
.map_err(D::Error::custom)?;
|
||||
let decoding_parameter =
|
||||
ShareDecodingParameter::<32>::Leader(bytes.len() / FieldPrio2::ENCODED_SIZE);
|
||||
let share = Share::<FieldPrio2, 32>::get_decoded_with_param(&decoding_parameter, &bytes)
|
||||
.map_err(D::Error::custom)?;
|
||||
assert_matches!(share, Share::Leader(vec) => Ok(vec))
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,5 +1,7 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! Tools for evaluating Prio3 test vectors.
|
||||
|
||||
use crate::{
|
||||
codec::{Encode, ParameterizedDecode},
|
||||
flp::Type,
|
||||
|
@ -58,19 +60,21 @@ macro_rules! err {
|
|||
|
||||
// TODO Generalize this method to work with any VDAF. To do so we would need to add
|
||||
// `shard_with_random()` to traits. (There may be a less invasive alternative.)
|
||||
fn check_prep_test_vec<M, T, P, const SEED_SIZE: usize>(
|
||||
fn check_prep_test_vec<MS, MP, T, P, const SEED_SIZE: usize>(
|
||||
prio3: &Prio3<T, P, SEED_SIZE>,
|
||||
verify_key: &[u8; SEED_SIZE],
|
||||
test_num: usize,
|
||||
t: &TPrio3Prep<M>,
|
||||
t: &TPrio3Prep<MS>,
|
||||
) -> Vec<OutputShare<T::Field>>
|
||||
where
|
||||
T: Type<Measurement = M>,
|
||||
MS: Clone,
|
||||
MP: From<MS>,
|
||||
T: Type<Measurement = MP>,
|
||||
P: Xof<SEED_SIZE>,
|
||||
{
|
||||
let nonce = <[u8; 16]>::try_from(t.nonce.clone()).unwrap();
|
||||
let (public_share, input_shares) = prio3
|
||||
.shard_with_random(&t.measurement, &nonce, &t.rand)
|
||||
.shard_with_random(&t.measurement.clone().into(), &nonce, &t.rand)
|
||||
.expect("failed to generate input shares");
|
||||
|
||||
assert_eq!(
|
||||
|
@ -86,7 +90,7 @@ where
|
|||
"#{test_num}"
|
||||
);
|
||||
assert_eq!(
|
||||
input_shares[agg_id].get_encoded(),
|
||||
input_shares[agg_id].get_encoded().unwrap(),
|
||||
want.as_ref(),
|
||||
"#{test_num}"
|
||||
)
|
||||
|
@ -110,14 +114,18 @@ where
|
|||
.unwrap_or_else(|e| err!(test_num, e, "decode test vector (prep share)")),
|
||||
"#{test_num}"
|
||||
);
|
||||
assert_eq!(prep_shares[i].get_encoded(), want.as_ref(), "#{test_num}");
|
||||
assert_eq!(
|
||||
prep_shares[i].get_encoded().unwrap(),
|
||||
want.as_ref(),
|
||||
"#{test_num}"
|
||||
);
|
||||
}
|
||||
|
||||
let inbound = prio3
|
||||
.prepare_shares_to_prepare_message(&(), prep_shares)
|
||||
.unwrap_or_else(|e| err!(test_num, e, "prep preprocess"));
|
||||
assert_eq!(t.prep_messages.len(), 1);
|
||||
assert_eq!(inbound.get_encoded(), t.prep_messages[0].as_ref());
|
||||
assert_eq!(inbound.get_encoded().unwrap(), t.prep_messages[0].as_ref());
|
||||
|
||||
let mut out_shares = Vec::new();
|
||||
for state in states.iter_mut() {
|
||||
|
@ -130,7 +138,11 @@ where
|
|||
}
|
||||
|
||||
for (got, want) in out_shares.iter().zip(t.out_shares.iter()) {
|
||||
let got: Vec<Vec<u8>> = got.as_ref().iter().map(|x| x.get_encoded()).collect();
|
||||
let got: Vec<Vec<u8>> = got
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|x| x.get_encoded().unwrap())
|
||||
.collect();
|
||||
assert_eq!(got.len(), want.len());
|
||||
for (got_elem, want_elem) in got.iter().zip(want.iter()) {
|
||||
assert_eq!(got_elem.as_slice(), want_elem.as_ref());
|
||||
|
@ -141,12 +153,14 @@ where
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
fn check_aggregate_test_vec<M, T, P, const SEED_SIZE: usize>(
|
||||
fn check_aggregate_test_vec<MS, MP, T, P, const SEED_SIZE: usize>(
|
||||
prio3: &Prio3<T, P, SEED_SIZE>,
|
||||
t: &TPrio3<M>,
|
||||
t: &TPrio3<MS>,
|
||||
) -> T::AggregateResult
|
||||
where
|
||||
T: Type<Measurement = M>,
|
||||
MS: Clone,
|
||||
MP: From<MS>,
|
||||
T: Type<Measurement = MP>,
|
||||
P: Xof<SEED_SIZE>,
|
||||
{
|
||||
let verify_key = t.verify_key.as_ref().try_into().unwrap();
|
||||
|
@ -167,85 +181,113 @@ where
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
for (got, want) in aggregate_shares.iter().zip(t.agg_shares.iter()) {
|
||||
let got = got.get_encoded();
|
||||
let got = got.get_encoded().unwrap();
|
||||
assert_eq!(got.as_slice(), want.as_ref());
|
||||
}
|
||||
|
||||
prio3.unshard(&(), aggregate_shares, 1).unwrap()
|
||||
}
|
||||
|
||||
/// Evaluate a Prio3 test vector. The instance of Prio3 is constructed from the `new_vdaf` callback,
|
||||
/// which takes in the VDAF parameters encoded by the test vectors and the number of shares.
|
||||
///
|
||||
/// This version allows customizing the deserialization of measurements, via an additional type
|
||||
/// parameter.
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub fn check_test_vec_custom_de<MS, MP, A, T, P, const SEED_SIZE: usize>(
|
||||
test_vec_json_str: &str,
|
||||
new_vdaf: impl Fn(&HashMap<String, serde_json::Value>, u8) -> Prio3<T, P, SEED_SIZE>,
|
||||
) where
|
||||
MS: for<'de> Deserialize<'de> + Clone,
|
||||
MP: From<MS>,
|
||||
A: for<'de> Deserialize<'de> + Debug + Eq,
|
||||
T: Type<Measurement = MP, AggregateResult = A>,
|
||||
P: Xof<SEED_SIZE>,
|
||||
{
|
||||
let t: TPrio3<MS> = serde_json::from_str(test_vec_json_str).unwrap();
|
||||
let vdaf = new_vdaf(&t.other_params, t.shares);
|
||||
let agg_result = check_aggregate_test_vec(&vdaf, &t);
|
||||
assert_eq!(agg_result, serde_json::from_value(t.agg_result).unwrap());
|
||||
}
|
||||
|
||||
/// Evaluate a Prio3 test vector. The instance of Prio3 is constructed from the `new_vdaf` callback,
|
||||
/// which takes in the VDAF parameters encoded by the test vectors and the number of shares.
|
||||
#[cfg(feature = "test-util")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
|
||||
pub fn check_test_vec<M, A, T, P, const SEED_SIZE: usize>(
|
||||
test_vec_json_str: &str,
|
||||
new_vdaf: impl Fn(&HashMap<String, serde_json::Value>, u8) -> Prio3<T, P, SEED_SIZE>,
|
||||
) where
|
||||
M: for<'de> Deserialize<'de> + Clone,
|
||||
A: for<'de> Deserialize<'de> + Debug + Eq,
|
||||
T: Type<Measurement = M, AggregateResult = A>,
|
||||
P: Xof<SEED_SIZE>,
|
||||
{
|
||||
check_test_vec_custom_de::<M, M, _, _, _, SEED_SIZE>(test_vec_json_str, new_vdaf)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
struct Prio3CountMeasurement(u8);
|
||||
|
||||
impl From<Prio3CountMeasurement> for bool {
|
||||
fn from(value: Prio3CountMeasurement) -> Self {
|
||||
value.0 != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_prio3_count() {
|
||||
for test_vector_str in [
|
||||
include_str!("test_vec/07/Prio3Count_0.json"),
|
||||
include_str!("test_vec/07/Prio3Count_1.json"),
|
||||
include_str!("test_vec/08/Prio3Count_0.json"),
|
||||
include_str!("test_vec/08/Prio3Count_1.json"),
|
||||
] {
|
||||
let t: TPrio3<u64> = serde_json::from_str(test_vector_str).unwrap();
|
||||
let prio3 = Prio3::new_count(t.shares).unwrap();
|
||||
|
||||
let aggregate_result = check_aggregate_test_vec(&prio3, &t);
|
||||
assert_eq!(aggregate_result, t.agg_result.as_u64().unwrap());
|
||||
check_test_vec_custom_de::<Prio3CountMeasurement, _, _, _, _, 16>(
|
||||
test_vector_str,
|
||||
|_json_params, num_shares| Prio3::new_count(num_shares).unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_prio3_sum() {
|
||||
for test_vector_str in [
|
||||
include_str!("test_vec/07/Prio3Sum_0.json"),
|
||||
include_str!("test_vec/07/Prio3Sum_1.json"),
|
||||
include_str!("test_vec/08/Prio3Sum_0.json"),
|
||||
include_str!("test_vec/08/Prio3Sum_1.json"),
|
||||
] {
|
||||
let t: TPrio3<u128> = serde_json::from_str(test_vector_str).unwrap();
|
||||
let bits = t.other_params["bits"].as_u64().unwrap() as usize;
|
||||
let prio3 = Prio3::new_sum(t.shares, bits).unwrap();
|
||||
|
||||
let aggregate_result = check_aggregate_test_vec(&prio3, &t);
|
||||
assert_eq!(aggregate_result, t.agg_result.as_u64().unwrap() as u128);
|
||||
check_test_vec(test_vector_str, |json_params, num_shares| {
|
||||
let bits = json_params["bits"].as_u64().unwrap() as usize;
|
||||
Prio3::new_sum(num_shares, bits).unwrap()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_prio3_sum_vec() {
|
||||
for test_vector_str in [
|
||||
include_str!("test_vec/07/Prio3SumVec_0.json"),
|
||||
include_str!("test_vec/07/Prio3SumVec_1.json"),
|
||||
include_str!("test_vec/08/Prio3SumVec_0.json"),
|
||||
include_str!("test_vec/08/Prio3SumVec_1.json"),
|
||||
] {
|
||||
let t: TPrio3<Vec<u128>> = serde_json::from_str(test_vector_str).unwrap();
|
||||
let bits = t.other_params["bits"].as_u64().unwrap() as usize;
|
||||
let length = t.other_params["length"].as_u64().unwrap() as usize;
|
||||
let chunk_length = t.other_params["chunk_length"].as_u64().unwrap() as usize;
|
||||
let prio3 = Prio3::new_sum_vec(t.shares, bits, length, chunk_length).unwrap();
|
||||
|
||||
let aggregate_result = check_aggregate_test_vec(&prio3, &t);
|
||||
let expected_aggregate_result = t
|
||||
.agg_result
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|val| val.as_u64().unwrap() as u128)
|
||||
.collect::<Vec<u128>>();
|
||||
assert_eq!(aggregate_result, expected_aggregate_result);
|
||||
check_test_vec(test_vector_str, |json_params, num_shares| {
|
||||
let bits = json_params["bits"].as_u64().unwrap() as usize;
|
||||
let length = json_params["length"].as_u64().unwrap() as usize;
|
||||
let chunk_length = json_params["chunk_length"].as_u64().unwrap() as usize;
|
||||
Prio3::new_sum_vec(num_shares, bits, length, chunk_length).unwrap()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_prio3_histogram() {
|
||||
for test_vector_str in [
|
||||
include_str!("test_vec/07/Prio3Histogram_0.json"),
|
||||
include_str!("test_vec/07/Prio3Histogram_1.json"),
|
||||
include_str!("test_vec/08/Prio3Histogram_0.json"),
|
||||
include_str!("test_vec/08/Prio3Histogram_1.json"),
|
||||
] {
|
||||
let t: TPrio3<usize> = serde_json::from_str(test_vector_str).unwrap();
|
||||
let length = t.other_params["length"].as_u64().unwrap() as usize;
|
||||
let chunk_length = t.other_params["chunk_length"].as_u64().unwrap() as usize;
|
||||
let prio3 = Prio3::new_histogram(t.shares, length, chunk_length).unwrap();
|
||||
|
||||
let aggregate_result = check_aggregate_test_vec(&prio3, &t);
|
||||
let expected_aggregate_result = t
|
||||
.agg_result
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|val| val.as_u64().unwrap() as u128)
|
||||
.collect::<Vec<u128>>();
|
||||
assert_eq!(aggregate_result, expected_aggregate_result);
|
||||
check_test_vec(test_vector_str, |json_params, num_shares| {
|
||||
let length = json_params["length"].as_u64().unwrap() as usize;
|
||||
let chunk_length = json_params["chunk_length"].as_u64().unwrap() as usize;
|
||||
Prio3::new_histogram(num_shares, length, chunk_length).unwrap()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"alpha": "0",
|
||||
"beta_inner": [
|
||||
[
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"2",
|
||||
"2"
|
||||
],
|
||||
[
|
||||
"3",
|
||||
"3"
|
||||
],
|
||||
[
|
||||
"4",
|
||||
"4"
|
||||
],
|
||||
[
|
||||
"5",
|
||||
"5"
|
||||
],
|
||||
[
|
||||
"6",
|
||||
"6"
|
||||
],
|
||||
[
|
||||
"7",
|
||||
"7"
|
||||
],
|
||||
[
|
||||
"8",
|
||||
"8"
|
||||
]
|
||||
],
|
||||
"beta_leaf": [
|
||||
"9",
|
||||
"9"
|
||||
],
|
||||
"binder": "736f6d65206e6f6e6365",
|
||||
"bits": 10,
|
||||
"keys": [
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"101112131415161718191a1b1c1d1e1f"
|
||||
],
|
||||
"public_share": "921909356f44964d29c537aeeaeba92e573e4298c88dcc35bd3ae6acb4367236226b1af3151d5814f308f04e208fde2110c72523338563bc1c5fb47d22b5c34ae102e1e82fa250c7e23b95e985f91d7d91887fa7fb301ec20a06b1d4408d9a594754dcd86ec00c91f40f17c1ff52ed99fcd59965fe243a6cec7e672fefc5e3a29e653d5dcca8917e8af2c4f19d122c6dd30a3e2a80fb809383ced9d24fcd86516025174f5183fddfc6d74dde3b78834391c785defc8e4fbff92214df4c8322ee433a8eaeed7369419e0d6037a536e081df333aaab9e8e4d207d846961f015d96d57e3b59e24927773d6e0d66108955c1da134baab4eacd363c8e452b8c3845d5fb5c0ff6c27d7423a73d32742ccc3c750a17cd1f6026dd98a2cf6d2bff2dd339017b25af23d6db00ae8975e3f7e6aaef4af71f3e8cd14eb5c4373db9c3a76fc04659b761e650a97cb873df894064ecb2043a4317ef237ffe8f130eb5c2ca2a132c16f14943cd7e462568c8544b82e29329eb2a"
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
{
|
||||
"agg_param": [
|
||||
0,
|
||||
[
|
||||
0,
|
||||
1
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"70f1cb8dc03c9eea88d270d6211a8667",
|
||||
"910e34723ec361157a2d8f29dde57998"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f311e448ab125690bc3a084a34301982c6aa325ab3f268338c9f4db9bda518743ee75c6c8ef7655d2d167d5385213d3bd1be920fad83c1b35fd9239efb406370db4d0a8e97eb41413957e264ded24e074ca433b6b5d451d0f65ec1d4ac246a36da12ecb2a537a449aeeb9d70bd064e930",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3f96998a1415c9876c2887f2dcc52f090ec64bcaeb3165e98f47d261a0bed49a156c054b063cad6277a526505ac31807288abfb796b6cee614e5c41ab75c2b9912cc246c66c5e248a7cfc30ad92eefec7e67c2da39726d5b7277eb1449c779f834b0ab75f383f07bd2f3747cb7b98f617c"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"70f1cb8dc03c9eea",
|
||||
"88d270d6211a8667"
|
||||
],
|
||||
[
|
||||
"910e34723ec36115",
|
||||
"7a2d8f29dde57998"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"d4cd54eb29f676c2d10fab848e6e85ebd51804e3562cf23b",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"bd68d28c9fff9a30f84122278759025501b83270bf27b41d",
|
||||
"1765825e8af6db91d9cd885d07158396d460d17297043e1e"
|
||||
],
|
||||
[
|
||||
"7c9659b7c681b4a4",
|
||||
"8569a648387e4b5b"
|
||||
]
|
||||
],
|
||||
"public_share": "b2c16aa5676c3188a74dff403c179dfb28c515d5a9892f38e5eb7be1c96bfdb0ebf761e6500e206a4ce363d09ab0a1d9b225e51798fd599f9dcd204058958c2d625646e5662534ff6650a9af834a248d46304f6d7a3b845f46c71433c833a86846147e264aaee1eb3e0bb19e53cd521e92ab9991265b731bfdb508fb164cd9d48d2c43953e7144a8b97e395bdd8aa2db7a1088f3bf8d245e15172e88764bba8271f6a19f70dc47a279e899394ea8658958",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
{
|
||||
"agg_param": [
|
||||
1,
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"d83fbcbf13566502f5849058b8b089e568a4e8aab8565425f69a56f809fc4527",
|
||||
"29c04340eba99afd0c7b6fa7464f761a995b175546a9abda0c65a907f503bad8"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f311e448ab125690bc3a084a34301982c6aa325ab3f268338c9f4db9bda518743ee75c6c8ef7655d2d167d5385213d3bd1be920fad83c1b35fd9239efb406370db4d0a8e97eb41413957e264ded24e074ca433b6b5d451d0f65ec1d4ac246a36da12ecb2a537a449aeeb9d70bd064e930",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3f96998a1415c9876c2887f2dcc52f090ec64bcaeb3165e98f47d261a0bed49a156c054b063cad6277a526505ac31807288abfb796b6cee614e5c41ab75c2b9912cc246c66c5e248a7cfc30ad92eefec7e67c2da39726d5b7277eb1449c779f834b0ab75f383f07bd2f3747cb7b98f617c"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"d83fbcbf13566502",
|
||||
"f5849058b8b089e5",
|
||||
"68a4e8aab8565425",
|
||||
"f69a56f809fc4527"
|
||||
],
|
||||
[
|
||||
"29c04340eba99afd",
|
||||
"0c7b6fa7464f761a",
|
||||
"995b175546a9abda",
|
||||
"0c65a907f503bad8"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"d45c0eabcc906acfb8239f3d0ef2b69a0f465979b04e355c",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"5d1b91841835491251436306076eaaa674d4b95b84b2a084",
|
||||
"77417d26b45b21bd68e03b3706840cf49c719f1d2b9c94d7"
|
||||
],
|
||||
[
|
||||
"6e703a28b5960604",
|
||||
"938fc5d74969f9fb"
|
||||
]
|
||||
],
|
||||
"public_share": "b2c16aa5676c3188a74dff403c179dfb28c515d5a9892f38e5eb7be1c96bfdb0ebf761e6500e206a4ce363d09ab0a1d9b225e51798fd599f9dcd204058958c2d625646e5662534ff6650a9af834a248d46304f6d7a3b845f46c71433c833a86846147e264aaee1eb3e0bb19e53cd521e92ab9991265b731bfdb508fb164cd9d48d2c43953e7144a8b97e395bdd8aa2db7a1088f3bf8d245e15172e88764bba8271f6a19f70dc47a279e899394ea8658958",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
{
|
||||
"agg_param": [
|
||||
2,
|
||||
[
|
||||
0,
|
||||
2,
|
||||
4,
|
||||
6
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"7ea47022f22f6be9bce8e0ee2eb522bcbc2d246c17704beed7043426b646fe26",
|
||||
"835b8fdd0cd0941645171f11d04add4345d2db93e78fb4112bfbcbd948b901d9"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f311e448ab125690bc3a084a34301982c6aa325ab3f268338c9f4db9bda518743ee75c6c8ef7655d2d167d5385213d3bd1be920fad83c1b35fd9239efb406370db4d0a8e97eb41413957e264ded24e074ca433b6b5d451d0f65ec1d4ac246a36da12ecb2a537a449aeeb9d70bd064e930",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3f96998a1415c9876c2887f2dcc52f090ec64bcaeb3165e98f47d261a0bed49a156c054b063cad6277a526505ac31807288abfb796b6cee614e5c41ab75c2b9912cc246c66c5e248a7cfc30ad92eefec7e67c2da39726d5b7277eb1449c779f834b0ab75f383f07bd2f3747cb7b98f617c"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"7ea47022f22f6be9",
|
||||
"bce8e0ee2eb522bc",
|
||||
"bc2d246c17704bee",
|
||||
"d7043426b646fe26"
|
||||
],
|
||||
[
|
||||
"835b8fdd0cd09416",
|
||||
"45171f11d04add43",
|
||||
"45d2db93e78fb411",
|
||||
"2bfbcbd948b901d9"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"6fb240ce8b8a2a8ce62112240f676105e0398515599f04b4",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"ca0f02c7c61655263bf76d954b8abd16eb6e5ce2b26911b2",
|
||||
"a5a23e07c573d565ac2aa48ec2dca3eef5ca2833a635f301"
|
||||
],
|
||||
[
|
||||
"f5171a3cc9d49422",
|
||||
"0ce8e5c3352b6bdd"
|
||||
]
|
||||
],
|
||||
"public_share": "b2c16aa5676c3188a74dff403c179dfb28c515d5a9892f38e5eb7be1c96bfdb0ebf761e6500e206a4ce363d09ab0a1d9b225e51798fd599f9dcd204058958c2d625646e5662534ff6650a9af834a248d46304f6d7a3b845f46c71433c833a86846147e264aaee1eb3e0bb19e53cd521e92ab9991265b731bfdb508fb164cd9d48d2c43953e7144a8b97e395bdd8aa2db7a1088f3bf8d245e15172e88764bba8271f6a19f70dc47a279e899394ea8658958",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
{
|
||||
"agg_param": [
|
||||
3,
|
||||
[
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
13,
|
||||
15
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"ec2be80f01fd1ded599b1a18d6ef112c400f421cca2c080d4ccc5cdd09562b3e556c1aaabe9dd47e8bc25979394c7bb5c61fd1db34b8dfdcc3eff4a5304fb7706b5462025bb400e644f2e0752f38098702491691494a2b498176ef41c4e6a962f716473c53087a3e80db0b9acb50cb15081b5ea4b50c48093f67a8c75875422dfd64ab2fa71fa3f3b55ec708ba4086672aff514d0cffe6f1c07f117c22af9b2c67b2a0c7ec1366ce474721174edb8b9eb33faef5f9c9d0c956e4407a86473120cfa46e8c634c1bc66c63a2009911f82c8426a45013e637aaba0e471b03f0a67a",
|
||||
"01d417f0fe02e212a664e5e72910eed3bff0bde335d3f7f2b333a322f6a9d4419893e55541622b81743da686c6b3844a39e02e24cb4720233c100b5acfb0480f82ab9dfda44bff19bb0d1f8ad0c7f678fdb6e96eb6b5d4b67e8910be3b19561df6e8b8c3acf785c17f24f46534af34eaf7e4a15b4af3b7f6c0985738a78abd52f09a54d058e05c0c4aa138f745bf7998d500aeb2f300190e3f80ee83dd506453874d5f3813ec9931b8b8dee8b12474614cc0510a06362f36a91bbf8579b8ce5f1e5b91739cb3e439939c5dff66ee07d37bd95bafec19c85545f1b8e4fc0f5905"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f311e448ab125690bc3a084a34301982c6aa325ab3f268338c9f4db9bda518743ee75c6c8ef7655d2d167d5385213d3bd1be920fad83c1b35fd9239efb406370db4d0a8e97eb41413957e264ded24e074ca433b6b5d451d0f65ec1d4ac246a36da12ecb2a537a449aeeb9d70bd064e930",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3f96998a1415c9876c2887f2dcc52f090ec64bcaeb3165e98f47d261a0bed49a156c054b063cad6277a526505ac31807288abfb796b6cee614e5c41ab75c2b9912cc246c66c5e248a7cfc30ad92eefec7e67c2da39726d5b7277eb1449c779f834b0ab75f383f07bd2f3747cb7b98f617c"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"ec2be80f01fd1ded599b1a18d6ef112c400f421cca2c080d4ccc5cdd09562b3e",
|
||||
"556c1aaabe9dd47e8bc25979394c7bb5c61fd1db34b8dfdcc3eff4a5304fb770",
|
||||
"6b5462025bb400e644f2e0752f38098702491691494a2b498176ef41c4e6a962",
|
||||
"f716473c53087a3e80db0b9acb50cb15081b5ea4b50c48093f67a8c75875422d",
|
||||
"fd64ab2fa71fa3f3b55ec708ba4086672aff514d0cffe6f1c07f117c22af9b2c",
|
||||
"67b2a0c7ec1366ce474721174edb8b9eb33faef5f9c9d0c956e4407a86473120",
|
||||
"cfa46e8c634c1bc66c63a2009911f82c8426a45013e637aaba0e471b03f0a67a"
|
||||
],
|
||||
[
|
||||
"01d417f0fe02e212a664e5e72910eed3bff0bde335d3f7f2b333a322f6a9d441",
|
||||
"9893e55541622b81743da686c6b3844a39e02e24cb4720233c100b5acfb0480f",
|
||||
"82ab9dfda44bff19bb0d1f8ad0c7f678fdb6e96eb6b5d4b67e8910be3b19561d",
|
||||
"f6e8b8c3acf785c17f24f46534af34eaf7e4a15b4af3b7f6c0985738a78abd52",
|
||||
"f09a54d058e05c0c4aa138f745bf7998d500aeb2f300190e3f80ee83dd506453",
|
||||
"874d5f3813ec9931b8b8dee8b12474614cc0510a06362f36a91bbf8579b8ce5f",
|
||||
"1e5b91739cb3e439939c5dff66ee07d37bd95bafec19c85545f1b8e4fc0f5905"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"4a2b97cf17e54b126a86c6791c50d6507ee8b74b3d9903bcf3881121bc6e0975c4efb2d8b8a132b8a6caa4eb39ac2bbb5bdc351604fa9e78d1a6f5a5f615bb0c8819f485d8b24a4e48da47d3b7458a9cfde1e85c66453319a3f6d43dc40a0135",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"4e64e5ed76c69ef68d3e144918a719986e40ab82f34bd30298b0085a3265d16988b8f646731ef47cb2fb1598e4cb817747623f1cc70ee7843ce1a9d6e3cf5c456801c9a3ae0c7c7663349a3daaf8fb51d165085c751e5bdd4e800df9e1e0193e",
|
||||
"fcc6b1e1a01ead1bdc47b23004a9bcb80fa80cc9494d30b95bd808c78909380b2937bc9145833e3bf4ce8e5355e0a943147af6f93cebb7f394c54bcf12465e470d182be229a6ced7e4a5ad950d4d8e4a2c7ce000f126d83b5476c744e229e776"
|
||||
],
|
||||
[
|
||||
"003c39f76240f6f9bcc6065a247b4432a651d5d72a35aff45928eec28c8a9d07",
|
||||
"edc3c6089dbf09064339f9a5db84bbcd59ae2a28d5ca500ba6d7113d73756278"
|
||||
]
|
||||
],
|
||||
"public_share": "b2c16aa5676c3188a74dff403c179dfb28c515d5a9892f38e5eb7be1c96bfdb0ebf761e6500e206a4ce363d09ab0a1d9b225e51798fd599f9dcd204058958c2d625646e5662534ff6650a9af834a248d46304f6d7a3b845f46c71433c833a86846147e264aaee1eb3e0bb19e53cd521e92ab9991265b731bfdb508fb164cd9d48d2c43953e7144a8b97e395bdd8aa2db7a1088f3bf8d245e15172e88764bba8271f6a19f70dc47a279e899394ea8658958",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"14be9c4ef7a6e12e963fdeac21cebdd4d36e13f4bc25306322e56303c62c90afd73f6b4aa9fdf33cb0afb55426d645ff8cd7e78cebf9d4f1087f6d4a033c8eae",
|
||||
"ed4163b108591ed14dc02153de31422b2e91ec0b43dacf9cc11a9cfc39d36f502bc094b556020cc333504aabd929ba007528187314062b0edb8092b5fcc37151"
|
||||
],
|
||||
"chunk_length": 2,
|
||||
"length": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"14be9c4ef7a6e12e963fdeac21cebdd4d36e13f4bc25306322e56303c62c90afd73f6b4aa9fdf33cb0afb55426d645ff8cd7e78cebf9d4f1087f6d4a033c8eaeec786d3b212d968c939de66318dbacafe73c1f5aa3e9078ba2f63ec5179e6b4694612c36f5d4d539d46dab1ac20e43963978d9dd36f19f31c83e58c903c2cd94215c68b15f5d6071e9e19fa973829dc71b536351b0db1072e77b7570e3e06c65fac248d21dd970f29640050e901d06775f05a897850cab5707ac25543ed6ce7061b9cd70c783e0483727236d0cbb05dafefd78ec4e6419efe93d6f82cdadbfd4e860661238040229f60205bbba983790303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": 2,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"14be9c4ef7a6e12e963fdeac21cebdd4",
|
||||
"d36e13f4bc25306322e56303c62c90af",
|
||||
"d73f6b4aa9fdf33cb0afb55426d645ff",
|
||||
"8cd7e78cebf9d4f1087f6d4a033c8eae"
|
||||
],
|
||||
[
|
||||
"ed4163b108591ed14dc02153de31422b",
|
||||
"2e91ec0b43dacf9cc11a9cfc39d36f50",
|
||||
"2bc094b556020cc333504aabd929ba00",
|
||||
"7528187314062b0edb8092b5fcc37151"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"7556ccbddbd14d509ee89124d31d1feb"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"806b1f8537500ce0b4b501b0ae5ed8f82679ba11ad995d6f605b000e32c41afb6d0070287fe7b99b8304d264cba1e3c6f4456e1c06f3b9d3d4947b2041c86b020d26c74d7663817e6a91960489806931b304fcd3755b43b96c806d2bbeb0166bbec7c61c35f886f3f539890522388f43",
|
||||
"8194e07ac8aff31f2f4afe4f51a12707b692a56a1745315a1022b4eb257b2a8725c610416af7b0d1a296f409cdb3fbf4f4c0d488206d794254e4755fd124cdc9a67364ddc7865afe3554de5f52f1ac910f3f8e110cfbad4113861316dc73ec60de4f6c512adaa41de631eda8d6d8c189"
|
||||
]
|
||||
],
|
||||
"public_share": "bec7c61c35f886f3f539890522388f43de4f6c512adaa41de631eda8d6d8c189",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"a6d2b4756e63a10bf5f650e258c73b0ccb20bace98e225dea29d625d527fdd4ded86beb9a0a0ac5c4216f5add7a297cece34b479a568a327f1e259839f813df97b34de254be5b9b9c8d9e56dbff50b7a6bf1e5967686755a1dc42e0ab170add8c88f8ca68f945e768a5007c775fd27cfecb4495e257a2f2f94ca48830aa16ec0decaeee645e295c5dc2ebe491aae1a7f17b2807fcb33ee08127db466067bf84ec613dac9c93adbe73dd262c1859b2865",
|
||||
"ed4163b108591ed14dc02153de31422b2e91ec0b43dacf9cc11a9cfc39d36f502bc094b556020cc333504aabd929ba007528187314062b0edb8092b5fcc3715126e16ce274ad58caaa14d22608269a4c41a256d3c9e847c0a6ac1a4fbaf6309e9ccbe74a9442ca956d843d6bd5adf9797a84557597d9cc81ddfa281ae5048d686bdb289ec2f3c96cdfa79b6974e6d15aec047748636d4358226283e11a78e045f59db2dda566162a56c85936ac0f4696",
|
||||
"6eebe7d888434023a1488dcac80682c8084e592524430a857f4701a673adb261eab8ac90085d47e06d99c0a64e33ae30bfa23313469131cafb9b13c763ba50b560eab4f73f6ded7b7011486b38e45939566cc395bf9042e5038fb6a6949821899ea48b0edc28d7f3cf2abbcdb454deb69cc6602c43ac034f563a8e62105a04d7b859e87af729a0cd2729a64c716b1326fe480838d15ece9eaf20c8b7de0c276b464e7358905e0eee4f654308ce549104"
|
||||
],
|
||||
"chunk_length": 3,
|
||||
"length": 11,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"a6d2b4756e63a10bf5f650e258c73b0ccb20bace98e225dea29d625d527fdd4ded86beb9a0a0ac5c4216f5add7a297cece34b479a568a327f1e259839f813df97b34de254be5b9b9c8d9e56dbff50b7a6bf1e5967686755a1dc42e0ab170add8c88f8ca68f945e768a5007c775fd27cfecb4495e257a2f2f94ca48830aa16ec0decaeee645e295c5dc2ebe491aae1a7f17b2807fcb33ee08127db466067bf84ec613dac9c93adbe73dd262c1859b2865508d344dda6c4339e650c401324c31481780ef7e7dcc07120ac004c05ab75ee5d22e2d0eb229dcdd3755fab49a1c2916e17c8ed2d975cfe76d576569bf05233c07f94417fccaf73d1cc33e17dae74650badffdd639a9b9f9e89de4b9fd13e258b90fbb2b3817b607dc14e6e5327746ca20d1f1918bce9714b135ffe01eb4e6aefab92b0462f7e676e26007e8c2e5a66e16f32f7c8457a6dfba39d9082f640006d560b4d64e86e2e2358c84e03b857c980f51b1a78b53f7cb44343ed184d8dc87ebf8698609eeefae5d8882224ebd28b9531015badea8ae9fe01c7495cafecdc4f13389ea4eb0bbce0a5ab85aa6fc06aabd96d28c84ecf039bfeb4c350049485f8a4c706a109164ff4c640edaedd0ad50820b1d1ed7ab08fc69c48b39aff1eebc02ef1ea40bd70784bfa50511c3dd64b107f4297842280c3cff8d94be202a0e2cb0090f3adb2189f445fcf291f452f162606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": 2,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"a6d2b4756e63a10bf5f650e258c73b0c",
|
||||
"cb20bace98e225dea29d625d527fdd4d",
|
||||
"ed86beb9a0a0ac5c4216f5add7a297ce",
|
||||
"ce34b479a568a327f1e259839f813df9",
|
||||
"7b34de254be5b9b9c8d9e56dbff50b7a",
|
||||
"6bf1e5967686755a1dc42e0ab170add8",
|
||||
"c88f8ca68f945e768a5007c775fd27cf",
|
||||
"ecb4495e257a2f2f94ca48830aa16ec0",
|
||||
"decaeee645e295c5dc2ebe491aae1a7f",
|
||||
"17b2807fcb33ee08127db466067bf84e",
|
||||
"c613dac9c93adbe73dd262c1859b2865"
|
||||
],
|
||||
[
|
||||
"ed4163b108591ed14dc02153de31422b",
|
||||
"2e91ec0b43dacf9cc11a9cfc39d36f50",
|
||||
"2bc094b556020cc333504aabd929ba00",
|
||||
"7528187314062b0edb8092b5fcc37151",
|
||||
"26e16ce274ad58caaa14d22608269a4c",
|
||||
"41a256d3c9e847c0a6ac1a4fbaf6309e",
|
||||
"9ccbe74a9442ca956d843d6bd5adf979",
|
||||
"7a84557597d9cc81ddfa281ae5048d68",
|
||||
"6bdb289ec2f3c96cdfa79b6974e6d15a",
|
||||
"ec047748636d4358226283e11a78e045",
|
||||
"f59db2dda566162a56c85936ac0f4696"
|
||||
],
|
||||
[
|
||||
"6eebe7d888434023a1488dcac80682c8",
|
||||
"084e592524430a857f4701a673adb261",
|
||||
"eab8ac90085d47e06d99c0a64e33ae30",
|
||||
"bfa23313469131cafb9b13c763ba50b5",
|
||||
"60eab4f73f6ded7b7011486b38e45939",
|
||||
"566cc395bf9042e5038fb6a694982189",
|
||||
"9ea48b0edc28d7f3cf2abbcdb454deb6",
|
||||
"9cc6602c43ac034f563a8e62105a04d7",
|
||||
"b859e87af729a0cd2729a64c716b1326",
|
||||
"fe480838d15ece9eaf20c8b7de0c276b",
|
||||
"464e7358905e0eee4f654308ce549104"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"4b7dc5c1b2a08aec5dcfc13de800559b"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"e80c098526d9321dd0801f97a648722016fa117f10cb2b062fc5fb1e55705894007f838333ef348c6306e141369bd88d123c66d2faeb132e330a73882c38765d425847bd86e5f784b3348ee4840c5df103b49f04c4dcca4667abb956187da58c91c946d9d5fdf496d95428f8a625dddfc8b7bb469397ebd4b177f902896febdaac39a8d9ec0aa1a24132036c2430929c",
|
||||
"4f6d4137ddffd58b243b8f845a1684550b240ea3e91a68335f717b83056e9b45c5e62d7a24da54147fcb9260d023cb7f9c8d036f0100f5fea0ce22f49e3d7672bc83fd5c724f2684f3442e8c5291c41509151808d1da447cddc3fe11cf5cd8d7fe662cf035eff88b583f6b32499b332aa6dee37947ef482e15fcb3a7f04b20813162d162b9bf30eee4953b6fdabd10f1",
|
||||
"ca85b543fc26f756ef4351e4fea0098a73787eeab8b613029af310882b7e87d28fc5502fd76bd704626d9f0f662e531feaf1fa912cc209de6541401d8508a4788d92e549f58241334cfa29abc1fb80a28ae61d7a4060d9582e3e20f182e4519ab1bb9547c545aafc21416e779856c80cf3690155119111aebf3800757989229e4966453f7aa269163b272848de80227f"
|
||||
]
|
||||
],
|
||||
"public_share": "ac39a8d9ec0aa1a24132036c2430929c3162d162b9bf30eee4953b6fdabd10f14966453f7aa269163b272848de80227f",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
256,
|
||||
257,
|
||||
258,
|
||||
259,
|
||||
260,
|
||||
261,
|
||||
262,
|
||||
263,
|
||||
264,
|
||||
265
|
||||
],
|
||||
"agg_shares": [
|
||||
"cdeb52d4615d1c718ef21a6560939efcb5024c89ea9b0f0018302087c0e978b5b5c84c8c4f217b14584cc3939963f56a2718c17af81d1f85129347fc73b2548262e047a67c3e0583eeef7c4a98a5da4ccdb558491081a00a8de5a46b8c2f299bc69162a7411b3ecf2b47670db337083dc50b8fc6d5c5d21da52fc7f538166b0e4564edd8fbb75bc8c4fdd0c02be2b6d11bc4a159297b72e2c635a9250feb2445",
|
||||
"3415ad2b9ea2e38e550de59a9f6c61034dfeb3761564f0ffcbcfdf783f16874a4e38b373b0de84eb8bb33c6c669c0a95dde83e8507e2e07ad16cb8038c4dab7da320b85983c1fa7cf50f83b5675a25b3394ba7b6ef7e5ff5561a5b9473d0d664416f9d58bee4c130b8b898f24cc8f7c243f570392a3a2de23ed0380ac7e994f1c49c12270448a4371f022f3fd41d492eef3c5ea6d6848d1d1dca56daf014dbba"
|
||||
],
|
||||
"bits": 8,
|
||||
"chunk_length": 9,
|
||||
"length": 10,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"2451f59efba2edc493c9246ff1f0e0a7f8f6f22ee46e662c899e485d7ce288d6becdfee804a39618972fbaa595eeec25423e412cbe51d44a62747de627630302368ec3535a2545a2799e8a0b9a144c811158dda278865d834b34fbe77ad11dbb9fdcf0637c24e10d5ab36d03cdc5f6b95e400a0a81608d96c25733c376376de3927c3570e8ab671358a1686d0c44ac938368d5621cff66585454ef124daa5f18efd7e791a4bcb11caf74b378e2c4feff3e5bad16e7c3fab987eb4d4a0c675bb4f4e70e1373fb00a5dd30a1118355c20e2e4c3700be3d3c1cf25d3e4a729836ba564aa074f99be0d23d4cc0dc9f263c986988e0d16a3d28c262d34f220b1ed127cddea3e2a1bd075c653d4b6f1c3d35e25d2804e7960250dea42dc4a52c9545bedc182ee8391b4c6849366af8e15f30bd06872e5ed651ef7db0b0c442886de32eeeeacc5f2dfe87f9375b4774153fc9e442105b5f8e452e80874c84131400d4d588a1a5d94bac9e68dbf917ef6405b0bc13fa89daf46f84405aedb166ac93f6545256b1da6ac65e01d580bb26eef82c34b9d728fc0c96ff898ed46bd289abbec9917397552ebf6d1eb3f916f69ee9f80e9466512bff70af2d8f3a9ed599f24e33550a09304e1b4f51948e2d8cbf5a1bb14455b1786ae3af4670111bc3983293ad9ae029128efd86d0a05cb3f442b43f466cec5cc9c4989bf5a29eb5c2401bc8bba0d5b7487bc0bf010c968fe76e3a9924459dce6704528d56540081240ed0d2f301a8c9baca5c183b1b5c3a9c03dce5036926d06e1470c2e63d15fdc3a61056154fca9439c595098ff3794c7d7e62af5e3139b43e22a0f8864c254a069a083604762d77ea000177a7b908efe27f6e00db7ea25f573734af803044fb2dc333ed9ad589d7677e23614143fa6836d68ed311dcedf0ea031688b2cf8c5248f21be444f1c61b050a0ab7dca04992673afb737bd27526a72dda3b03dad4d3b0bb81f0887ee6f25ec4cf35d58ea5f085e97609cfb6a8e97d84fdf8755b8e81ff29614bf1b03bcd2b8d9ab06dc4d60785f83eb6ee4573859223214ecdad734d114e15e1971a8b82222910fd041a1123a4e792a9239f99252de3e3e8d5bb209e2c9bda506a79853c482546940364a8246392fb5e18e85847458445fe3a970b29db6d3d0e4a806cfec7c8538f24896d2d10669113f2b724161d2007ee75c0b651f4934046142b04b2015212997c609625bbeb81b9fa0249c167196557c08ae9ea2defcf7859eed4d35b2183c628cb82fe01255e558e7c8b13bded6ba43ed8b92f6ba7879b39932468260c5768ca0909aae899ad1252c5dbcd741d971f179bc36e88a0a10981f73202cb25db324da405fdd5ca5331431afe362c5f933b3c1216c3e19140cd27f7c2ef67898887856a46a518a3afec78ee0d9dce778289a38d2df906932c40019afadab12fe7d0695316e5a3c1e38aa630a44bc8cc01a5a8cae060b7de435e54963b9354182d64e340ec9dc3e37f8b2bbaaab23608b86827991df4367839f443c160c1eb77f41159f69592c3eb37c21a521afcd34036a13a145e9cb1039704b8e523359ea5c3a50f705118ea7d8b1063eb85bfcdc941e0235579e97856ee6f6bfe9c4d0d161b5662de26a2fbddc530ce918a98514903c63a3476d6ebe68e2503e6bf255691fbd8a006e9c77f5a4ad9e3e8d21a56bc4f7bc90d61ebb31eaa4dce48eb9a8069a584ae35266a4bc4af970860d2e9a0df7b87e8fc8b597e73a85d8eeb91def6057d7a77e8f859ee9ee07ef2fb2260660e59ee16458eafbd7bab979ed9bf72c1c27cadc9011f563aeed9a4b2f09ce5455857bcf3acbe0e1cf15537594469c777a885ad24ac5a8c894a8257c5212fb46184ad7f280bc25600129b25bf941460fcdd2e45a0216f1f2fec84d4792a15f877d15c649991ef998621a50a04251257ed6ccd803fdbc83ce4b5c4d7e8ee4487848768384e0b3970ec899dfb423560e755c4716deb3e188ca780cc7a97e8fb80076e9c44c6b7575725253ae4605844c3748bf90c14f17ee80a42fea450c05eb1f251eb09855f2ab368047d68cd7f4b8898d0113d52117375eed77707e7abff8554dc7da30cca674ac587198c0f165a47a5db79e9cc1c7bda9cdc36b94f14141a307850062f4d7208b8c612691699e3e3c16c3fc2dc6604e0fcb27acd6b5d326d2663a3f819589176c70423bc4d37d8c2a17e97468cf923a5388eb0d1de61358e9651a7e76b033d32d6c84e7ed5831a990b46e8228b6ef120643049645b82e100a7ed6ddd2ebfe2dcbd8b0e7ac1e5ee021d4279f164acc47875ade2c0acff5dbbf3a6eb0e8601632c926780be1660270420aa02c99fb39af1852b09904791e90cfa1f02aec0ab2de111524394819527819e52d495196ab3aff1e323dfec07af91e18b9a04e37552a23b13177bdcfc64ec7108e5e9b3679ccdf6b1e998e2bbcd5fbbbebf5ad8008e727cae6499cc06aa03809947e298683a4340f51d6eecad38d0a7a5437dd6e72bce6543b81fd3a438d71e232845cdb403f1011295f9aee5e33352b86e92343985884284c9646da13545f37b9d6da7d0cf902c19a5ca1f4f1818a2c2644807fcc54be35c29f96fb4fea5efdc88b270f1c5504bd8ba558834786020cc2f03ab5c56eaea38532b9faf6208f57d970b2e5ff92872713c9e0ad07b26e72dca6f9a9c02bad6c9db4d1d738f306292f14415d2856c2b073c5d8faf89e9713ceb375b6eefabc240bf6c6bf39cafb99993767dbaf5ee5f4b3f93e638e904fb55f443312c145b809fd203b5b3a16bd229b952e100bbfc0e49bbd05d54c3e5fa1a44fe55de16cfa52f3b169e0bfe95b1b8b6367f9309adfe3df079104fd720d46d772def3c0534d73615071fa22a79af875f796478d2f599dbb4c1ed303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"9aa31b9c201fb42526a6b32120318aa9",
|
||||
"e8551983a3deafaafe0f608295f8d291",
|
||||
"3eed6ed96f607eb1be6e96868876fc78",
|
||||
"65b295d3525f0ad74886c2fe7b3b1cd6",
|
||||
"794a6d37d41457d6f04fd418888cf36e",
|
||||
"483cc86d052be058d0a1e12384ba0d89",
|
||||
"9c85cb376b5ebfeffb6c22af3bbd02bf",
|
||||
"9c0385979cecf00983ba97fc12b2235a",
|
||||
"c7cbf9f2533dc942eca94540b9a0e745",
|
||||
"0f418bc80d2926f6ec11e3615a4e0c17"
|
||||
],
|
||||
[
|
||||
"675ce463dfe04bdabd594cdedfce7556",
|
||||
"1aaae67c5c215055e5ef9f7d6a072d6e",
|
||||
"c5129126909f814e2591697977890387",
|
||||
"9f4d6a2cada0f5289b793d0184c4e329",
|
||||
"8cb592c82beba829f3af2be777730c91",
|
||||
"bec33792fad41fa7135e1edc7b45f276",
|
||||
"6b7a34c894a14010e892dd50c442fd40",
|
||||
"6cfc7a6863130ff660456803ed4ddca5",
|
||||
"4234060dacc236bdf755babf465f18ba",
|
||||
"fbbe7437f2d6d909f7ed1c9ea5b1f3e8"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"db085315822777376b4d0f962d8f06d9"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"e6a4fe7264f95c384446bd51db14f78e7f4133afed0604aeb3b87125fc076c7447d795723adfe93d85f9fe2993c52420e45694fd2ec164a54a7267ee5efc8cb40b6659ac81f2e850786218bcec469ec4f7bb28e875d75ee98d54d566186c61c35448a50cb11e195d886622861a78bbb74325b7972e7b4c47f0e2e10a15d7a33c3daecb2dfc507b1b6676c1e9bfc52a4873f408a5788e7b77ce6943e67f3f457280544d93b81b08e427f699ba54adcbb0ffab83366d9b336846c0c989f0bc25bdd14683f1a85e844b9dbac26daae84cc8d57ef6b0c340798ac5ade63150e8d7a9673b64d798a97cf2715f399fd371e342c1ad50e28431f54180ef63ad7dd21f3e5d8d67159cacfd56f5d99c39d53047c8d7bf11ad83a2e3e569e1393b12d87d01701fa71b50b51e092ca6b797bb97890efb6327f1c4e488663dca5f00675c2af7368a9ab95b3c4e9e1a8dd5430d336833",
|
||||
"1b5b018d9b06a3c79fb942ae24eb087131693625114418115cb3e54a45056eabd0f6e371501957e00796db78ea8f3388eb8345e938f5fbdd8b24c3a968276d7c457ff43ce93631942f823f5bb9c6d1335b8022e804072711cb8fa5fb3afb209e696c9cac47da44cdc3eb3874eb0d8c89692408b463df12bb2d6e8193d5829cce221e486a579b91cd10a0fb38fec7214a9008d574ba32615f6215aef827a2962a31df892814bd8b8f828d029f07f6acf490e7ecd3377f10b86ec2d5741ba37a3a9522b897e840e315a614a89d0bcf8296bdd45e330eaf3f34b3ce4e1dd41306eae92147fc6676eedff2cb239581f46750df341390e066dabb01ef6362694f923d5a65dbc5252a8da8702a979aca3e211af7124485c1c7dc68f6fb1bdfb9a4d0d993cece17c818d8fb1151f1ef1b32745f09c155f42259af588b424c1dafe8d0e90a3dfc6f55bb428773ce15071cb720fb"
|
||||
]
|
||||
],
|
||||
"public_share": "368a9ab95b3c4e9e1a8dd5430d3368330a3dfc6f55bb428773ce15071cb720fb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"2551f59efba2edc493c9246ff1f0e0a7f8f6f22ee46e662c899e485d7ce288d6becdfee804a39618972fbaa595eeec25423e412cbe51d44a62747de627630302368ec3535a2545a2799e8a0b9a144c811158dda278865d834b34fbe77ad11dbb9fdcf0637c24e10d5ab36d03cdc5f6b95e400a0a81608d96c25733c376376de3927c3570e8ab671358a1686d0c44ac938368d5621cff66585454ef124daa5f18efd7e791a4bcb11caf74b378e2c4feff3e5bad16e7c3fab987eb4d4a0c675bb4f4e70e1373fb00a5dd30a1118355c20e2e4c3700be3d3c1cf25d3e4a729836ba564aa074f99be0d23d4cc0dc9f263c986988e0d16a3d28c262d34f220b1ed127cedea3e2a1bd075c653d4b6f1c3d35e25c2804e7960250dea42dc4a52c9545bedc182ee8391b4c6849366af8e15f30bd06872e5ed651ef7db0b0c442886de32eeeeacc5f2dfe87f9375b4774153fc9e442105b5f8e452e80874c84131400d4d588a1a5d94bac9e68dbf917ef6405b0bc13fa89daf46f84405aedb166ac93f6545256b1da6ac65e01d580bb26eef82c34b8d728fc0c96ff898ed46bd289abbec9917397552ebf6d1eb3f916f69ee9f80e9466512bff70af2d8f3a9ed599f24e33550a09304e1b4f51948e2d8cbf5a1bb14455b1786ae3af4670111bc3983293ad9ae029128efd86d0a05cb3f442b43f466cec5cc9c4989bf5a29eb5c2401bc8bba1d5b7487bc0bf010c968fe76e3a9924459dce6704528d56540081240ed0d2f300a8c9baca5c183b1b5c3a9c03dce5036926d06e1470c2e63d15fdc3a61056154fca9439c595098ff3794c7d7e62af5e3139b43e22a0f8864c254a069a083604762d77ea000177a7b908efe27f6e00db7ea25f573734af803044fb2dc333ed9ad589d7677e23614143fa6836d68ed311dcedf0ea031688b2cf8c5248f21be444f0c61b050a0ab7dca04992673afb737bd27526a72dda3b03dad4d3b0bb81f0887ee6f25ec4cf35d58ea5f085e97609cfb6a8e97d84fdf8755b8e81ff29614bf1b03bcd2b8d9ab06dc4d60785f83eb6ee4573859223214ecdad734d114e15e1971b8b82222910fd041a1123a4e792a9239e99252de3e3e8d5bb209e2c9bda506a78853c482546940364a8246392fb5e18e85847458445fe3a970b29db6d3d0e4a806cfec7c8538f24896d2d10669113f2b724161d2007ee75c0b651f4934046142b04b2015212997c609625bbeb81b9fa0249c167196557c08ae9ea2defcf7859eed4d35b2183c628cb82fe01255e558e7b8b13bded6ba43ed8b92f6ba7879b39922468260c5768ca0909aae899ad1252c5dbcd741d971f179bc36e88a0a10981f73202cb25db324da405fdd5ca5331431afe362c5f933b3c1216c3e19140cd27f7c2ef67898887856a46a518a3afec78ee0d9dce778289a38d2df906932c40019bfadab12fe7d0695316e5a3c1e38aa630a44bc8cc01a5a8cae060b7de435e54963b9354182d64e340ec9dc3e37f8b2bb9aab23608b86827991df4367839f443c160c1eb77f41159f69592c3eb37c21a521afcd34036a13a145e9cb1039704b8e523359ea5c3a50f705118ea7d8b1063eb85bfcdc941e0235579e97856ee6f6bfe9c4d0d161b5662de26a2fbddc530ce918a98514903c63a3476d6ebe68e2503e6bf255691fbd8a006e9c77f5a4ad9e3e7d21a56bc4f7bc90d61ebb31eaa4dce48eb9a8069a584ae35266a4bc4af970860d2e9a0df7b87e8fc8b597e73a85d8eeb91def6057d7a77e8f859ee9ee07ef2fb2260660e59ee16458eafbd7bab979ed9bf72c1c27cadc9011f563aeed9a4b2f09ce5455857bcf3acbe0e1cf15537594469c777a885ad24ac5a8c894a8257c5212fb46184ad7f280bc25600129b25bf941460fcdd2e45a0216f1f2fec84d4792a15f877d15c649991ef998621a50a04251257ed6ccd803fdbc83ce4b5c4d7e8ee4487848768384e0b3970ec899dfb423560e755c4716deb3e188ca780cc7a97e8fb80076e9c44c6b7575725253ae4605844c3748bf90c14f17ee80a42fea450c05eb1f251eb09855f2ab368047d68cd7f4b8898d0113d52117375eed77707e7abff8554dc7da30cca674ac587198c0f165a47a5db79e9cc1c7bda9cdc36b94f14141a307850062f4d7208b8c612691699e3e3c16c3fc2dc6604e0fcb27acd6b5d326d2663a3f819589176c70423bc4d42a21c0a30addfe4b4176740f9a418eca631cda9a8b94d20c7f9b834ed87751464dc5e5b446d920312003e4673b48c6c12b407af1ed90002507883f78d166f0b90bc14ed77d4aec6220cdd51948cdad29ab70513aadccd0e3c8c8108d3b0722602d9612aa6feb323a4ff3e8fe0e3d5701467491acdd3c71c34bc019047647779922216ccd61c47958461e3017adf446c4bd2ab7fbf70e41419679f6a9b3fa4c9aa5e9ef8469ace0d88bc35a3374f462573d2ba24b712359ef36e413006a9883bfa4fad43d89c7f1732725e3cad482d17a9499e1fb0f57d1ca93cafa7fd6d654a70cd7318bd7ace30e981217317105bcfe5e33352b86e92343985884284c9646d966beb8aca87d44e15dcce24aeb08312091cd98e6b52e2525409c58438f00131d33ce09fde0343f84db73369954f2d77a3a559189bc4dfd7e7c043b1364b36550595f624483c4eccccb1c4958a9284e43522dcc72ad9b01162d964605eab990dd1ddd25796f55991e1201f22526117662c0cad518f191effe5608b444b9e8973f5a11a8c154bc501bc47bb4fb5832d67f4c5ea5c221e64ff88ff5d5117aadac704a8b94beb036e87fc9a9462c355231b9bbe8a9122f12390073600f2d7f6262f1758eced79619900cad1910286c5bae553c6525c63c52ca97bf452957c5fc1a7d695dcb5ed0cf0004454c528d63960cd303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"9ba31b9c201fb42526a6b32120318aa9",
|
||||
"e8551983a3deafaafe0f608295f8d291",
|
||||
"3ded6ed96f607eb1be6e96868876fc78",
|
||||
"63b295d3525f0ad74886c2fe7b3b1cd6",
|
||||
"764a6d37d41457d6f04fd418888cf36e",
|
||||
"443cc86d052be058d0a1e12384ba0d89",
|
||||
"9785cb376b5ebfeffb6c22af3bbd02bf",
|
||||
"960385979cecf00983ba97fc12b2235a",
|
||||
"c0cbf9f2533dc942eca94540b9a0e745",
|
||||
"07418bc80d2926f6ec11e3615a4e0c17"
|
||||
],
|
||||
[
|
||||
"675ce463dfe04bdabd594cdedfce7556",
|
||||
"1aaae67c5c215055e5ef9f7d6a072d6e",
|
||||
"c5129126909f814e2591697977890387",
|
||||
"9f4d6a2cada0f5289b793d0184c4e329",
|
||||
"8cb592c82beba829f3af2be777730c91",
|
||||
"bec33792fad41fa7135e1edc7b45f276",
|
||||
"6b7a34c894a14010e892dd50c442fd40",
|
||||
"6cfc7a6863130ff660456803ed4ddca5",
|
||||
"4234060dacc236bdf755babf465f18ba",
|
||||
"fbbe7437f2d6d909f7ed1c9ea5b1f3e8"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"fdecd6d197e824492dd550fcdd0aa3c7"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"e6a4fe7264f95c384446bd51db14f78eec654b5beb7d60677c0b8385ca51a5bf896c79a069b04f339fdcb675885a26f533ec0d6e805beef6d7683a8ecdfa46cb87fdbc532efa5b1041347ed94f54fbca15041d013729d5eb78dcb1a1c293e0035448a50cb11e195d886622861a78bbb7bccc68d521fac002ece757cc5d82afb3b0f9f8766a1714047b50417a8e7f63eacf222c675bdf1d3e8362806ef5f9c16c446a1e5e06ce539aa300bc68c837c9207c5dbc7d85f896fb1be725e461ceacd303716a2cd8005e370a8ac1062d966b5c1499813d0dc63d697c4fd44dcfe81b3cfc37952de43649650c52ca9f2044fd3dfc42cd08bf0659e6a7facee2468ad1b07903a933ec3cbd06a5f81461e434449c32ef6678f3c8fd250c0b3318e80235144a96f07af2169dfddb503b38a2039f80f6bdfbbec6b3ad1025a43a90249221d20e627a73e2ed92bf1920574f42775675",
|
||||
"1b5b018d9b06a3c79fb942ae24eb0871aba638b677efec2418d7921020c44ff8d0f6e371501957e00796db78ea8f338813d41fd058418e6056a93bb2785cec1d457ff43ce93631942f823f5bb9c6d133fbfbf9d10fa7922dccd1e570b0246775696c9cac47da44cdc3eb3874eb0d8c89fcdfd722a57116825749c8972129304c221e486a579b91cd10a0fb38fec7214af0fe63f4a24e9e189e180a8aaed3b22931df892814bd8b8f828d029f07f6acf402eb7c22aea07b55e871ebdf6475ae509522b897e840e315a614a89d0bcf8296c0b0d5b745f277689643e3da46c09a1ce92147fc6676eedff2cb239581f46750fa1947870c81f9d565f51ed7e09d86dc5a65dbc5252a8da8702a979aca3e211ae9def20e5f2fa85d16e3ccb0a917510793cece17c818d8fb1151f1ef1b32745f09c155f42259af588b424c1dafe8d0e90a3dfc6f55bb428773ce15071cb720fb"
|
||||
]
|
||||
],
|
||||
"public_share": "0e627a73e2ed92bf1920574f427756750a3dfc6f55bb428773ce15071cb720fb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"2551f59efba2edc493c9246ff1f0e0a7f9f6f22ee46e662c899e485d7ce288d6bfcdfee804a39618972fbaa595eeec25433e412cbe51d44a62747de627630302378ec3535a2545a2799e8a0b9a144c811258dda278865d834b34fbe77ad11dbba0dcf0637c24e10d5ab36d03cdc5f6b95f400a0a81608d96c25733c376376de3927c3570e8ab671358a1686d0c44ac938468d5621cff66585454ef124daa5f18f0d7e791a4bcb11caf74b378e2c4feff3f5bad16e7c3fab987eb4d4a0c675bb4f5e70e1373fb00a5dd30a1118355c20e2f4c3700be3d3c1cf25d3e4a729836ba574aa074f99be0d23d4cc0dc9f263c986a88e0d16a3d28c262d34f220b1ed127cedea3e2a1bd075c653d4b6f1c3d35e25d2804e7960250dea42dc4a52c9545bedd182ee8391b4c6849366af8e15f30bd07872e5ed651ef7db0b0c442886de32eefeacc5f2dfe87f9375b4774153fc9e443105b5f8e452e80874c84131400d4d589a1a5d94bac9e68dbf917ef6405b0bc14fa89daf46f84405aedb166ac93f6545256b1da6ac65e01d580bb26eef82c34b9d728fc0c96ff898ed46bd289abbec9927397552ebf6d1eb3f916f69ee9f80e9566512bff70af2d8f3a9ed599f24e33560a09304e1b4f51948e2d8cbf5a1bb14555b1786ae3af4670111bc3983293ad9be029128efd86d0a05cb3f442b43f466dec5cc9c4989bf5a29eb5c2401bc8bba1d5b7487bc0bf010c968fe76e3a9924469dce6704528d56540081240ed0d2f301a8c9baca5c183b1b5c3a9c03dce5036a26d06e1470c2e63d15fdc3a610561550ca9439c595098ff3794c7d7e62af5e3239b43e22a0f8864c254a069a083604772d77ea000177a7b908efe27f6e00db7fa25f573734af803044fb2dc333ed9ad589d7677e23614143fa6836d68ed311ddedf0ea031688b2cf8c5248f21be444f1c61b050a0ab7dca04992673afb737bd37526a72dda3b03dad4d3b0bb81f0887fe6f25ec4cf35d58ea5f085e97609cfb7a8e97d84fdf8755b8e81ff29614bf1b13bcd2b8d9ab06dc4d60785f83eb6ee4673859223214ecdad734d114e15e1971b8b82222910fd041a1123a4e792a9239f99252de3e3e8d5bb209e2c9bda506a79853c482546940364a8246392fb5e18e95847458445fe3a970b29db6d3d0e4a816cfec7c8538f24896d2d10669113f2b824161d2007ee75c0b651f4934046142c04b2015212997c609625bbeb81b9fa0349c167196557c08ae9ea2defcf7859eed4d35b2183c628cb82fe01255e558e7c8b13bded6ba43ed8b92f6ba7879b39932468260c5768ca0909aae899ad1252c6dbcd741d971f179bc36e88a0a10981f83202cb25db324da405fdd5ca5331431bfe362c5f933b3c1216c3e19140cd27f8c2ef67898887856a46a518a3afec78ef0d9dce778289a38d2df906932c40019bfadab12fe7d0695316e5a3c1e38aa631a44bc8cc01a5a8cae060b7de435e54973b9354182d64e340ec9dc3e37f8b2bbaaab23608b86827991df4367839f443c260c1eb77f41159f69592c3eb37c21a531afcd34036a13a145e9cb1039704b8e623359ea5c3a50f705118ea7d8b1063ec85bfcdc941e0235579e97856ee6f6bfe9c4d0d161b5662de26a2fbddc530ce928a98514903c63a3476d6ebe68e2503e7bf255691fbd8a006e9c77f5a4ad9e3e8d21a56bc4f7bc90d61ebb31eaa4dce49eb9a8069a584ae35266a4bc4af970861d2e9a0df7b87e8fc8b597e73a85d8eec91def6057d7a77e8f859ee9ee07ef2fc2260660e59ee16458eafbd7bab979ed9bf72c1c27cadc9011f563aeed9a4b2f09ce5455857bcf3acbe0e1cf15537594469c777a885ad24ac5a8c894a8257c5212fb46184ad7f280bc25600129b25bf941460fcdd2e45a0216f1f2fec84d4792a15f877d15c649991ef998621a50a04251257ed6ccd803fdbc83ce4b5c4d7e8ee4487848768384e0b3970ec899dfb423560e755c4716deb3e188ca780cc7a97e8fb80076e9c44c6b7575725253ae4605844c3748bf90c14f17ee80a42fea450c05eb1f251eb09855f2ab368047d68cd7f4b8898d0113d52117375eed77707e7abff8554dc7da30cca674ac587198c0f165a47a5db79e9cc1c7bda9cdc36b94f14141a307850062f4d7208b8c612691699e3e3c16c3fc2dc6604e0fcb27acd6b5d326d2663a3f819589176c70423bc4dc97f402ea5053f2aa068d42c371d327339bd8637472eb9be88e409688a53bff392a8891c96c7804998d761fcf34dbf8da8cb17567f75ab4be29ecb6c33c85bf572b645bb7b226e4b99ccc0d959e6d809ec45b70cefe5ada611ea14962c9788d3e15100872669baf3c07a424cc205db97c0e2f72880a40a48d3820f89a16c7ee9dbc44bea18d787e0b730093a7b1fe4f9fd3e50128c61f6d4179fde88b02629629bf9f56f15abe3860ad2c99eaee9eba2310ca898fee5103f7bcb11ec9f4154007cf7d2b51a173331576526665d9f90879a2122b2bdef3a2cff68e57b146ae6d99a4e247d0daa693ef0a07aadc1a4b25ce5e33352b86e92343985884284c9646d0f8ec766552f75092a8b613870386a8b77901f01cddd76b4761e74519b24b851a570b5de8ca954b2c7df0fb314b6fa550e8e49713a28358e399afb3b9199496b229bc55644ee8e4772f1e00dc53886ade4932acee5cfd079707bd1d204c58360f26434fb158b53c1c4a51b65703f123f8090fe42dc48dbd3469a7d4bf1958203adffe46dd39084b66c789517b4438ed9415946ca552d523fa6c71e3302c3552f140d62d41cf3580e5e8500674cbb7d9ddd849d1ddb1d48ef7fd92f363e5e5b6a95b0c67b37e7e5e6a4dec9d8d56e577562eecec955cb6f9925c81cc165634018ab142c519ddd54f358356cee2ba50840303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"99a41b9c201fb42526a6b32120318aa9",
|
||||
"e6561983a3deafaafe0f608295f8d291",
|
||||
"3bee6ed96f607eb1be6e96868876fc78",
|
||||
"61b395d3525f0ad74886c2fe7b3b1cd6",
|
||||
"744b6d37d41457d6f04fd418888cf36e",
|
||||
"423dc86d052be058d0a1e12384ba0d89",
|
||||
"9586cb376b5ebfeffb6c22af3bbd02bf",
|
||||
"940485979cecf00983ba97fc12b2235a",
|
||||
"beccf9f2533dc942eca94540b9a0e745",
|
||||
"05428bc80d2926f6ec11e3615a4e0c17"
|
||||
],
|
||||
[
|
||||
"675ce463dfe04bdabd594cdedfce7556",
|
||||
"1aaae67c5c215055e5ef9f7d6a072d6e",
|
||||
"c5129126909f814e2591697977890387",
|
||||
"9f4d6a2cada0f5289b793d0184c4e329",
|
||||
"8cb592c82beba829f3af2be777730c91",
|
||||
"bec33792fad41fa7135e1edc7b45f276",
|
||||
"6b7a34c894a14010e892dd50c442fd40",
|
||||
"6cfc7a6863130ff660456803ed4ddca5",
|
||||
"4234060dacc236bdf755babf465f18ba",
|
||||
"fbbe7437f2d6d909f7ed1c9ea5b1f3e8"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"190c0ef07d6f2cbd1bed12d71b5f118d"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"e6a4fe7264f95c384446bd51db14f78ef1ffdfc96013014baff7bd0684b8ff3360f6a2a23b1d7b71796b845eeb21e7d1682128dc8b87837803fec0e3bd6c548d5cc9c041a482cbfc38120743a2f1a0985053eaeccc339c56c2edf76451e22c9a1bca6ab2181850f44d904964d1f227a970e70b59328028ddafdb1649a8c4f1f7cbeb366e42f8603a7b627f7519f25617a33726ede06ab438714b4bd3cda025dc2bcab64974eb02b9e2a23bf0cab4e5ef1e87bb1a72767098c768a20e1090a712ed38c1e8803fd18181cc0069355b40f5f98ff3cbd2b31022df719d9c660e7d5bab239819730ad9165a38641379444093ba148996166ccf5e2826bddb7a7dc8eda4dd5928b12e1ea715538788804b5ce231dfc98ff45027ff8cb1f92007f2339621201a7dc483c83bb6df082105cb5f5d9eda1f847b3d43b4e16502062d5a4a158f651439d7666c683a6283d308c91b25",
|
||||
"1b5b018d9b06a3c79fb942ae24eb08714d70b996c916bc83063fda0f9ec82780d0f6e371501957e00796db78ea8f338874640cdcd2ca1496ea55d62aa3709498457ff43ce93631942f823f5bb9c6d133b1f04db02cc745245af6a31e4dfe912a696c9cac47da44cdc3eb3874eb0d8c89cc603d2ceec1678996fe311424b56e65221e486a579b91cd10a0fb38fec7214a46c9ce7f890afed4efa31fb5ca8766ae31df892814bd8b8f828d029f07f6acf47620063e9fa98ab947b376e068b9be689522b897e840e315a614a89d0bcf8296332affc2e6b52204d1d7994260e415c6e92147fc6676eedff2cb239581f4675066213f3b302497abbf10c1729131a0125a65dbc5252a8da8702a979aca3e211afb99a0edb76c92f2bd5941c6071db19d93cece17c818d8fb1151f1ef1b32745f09c155f42259af588b424c1dafe8d0e90a3dfc6f55bb428773ce15071cb720fb"
|
||||
]
|
||||
],
|
||||
"public_share": "8f651439d7666c683a6283d308c91b250a3dfc6f55bb428773ce15071cb720fb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
45328,
|
||||
76286,
|
||||
26980
|
||||
],
|
||||
"agg_shares": [
|
||||
"598a4207618eab7bd108c110106e84cd9498b18b79cace4b383274cef0ab280eae74b07f9a7f087a89a4f51f3adb97ed",
|
||||
"ea61abdf14b8477f6de1b47a18ac778ad0149cb235e666ccce92a9246a2858403e5903013ab179dcf6719d10fccdf589",
|
||||
"cfc412198ab90c0589158a74d7e503a89b7cb3c1504fcae7dc3ae20ca52b7fb17a9b4c7f2bcf7da947e96ccfc9567288"
|
||||
],
|
||||
"bits": 16,
|
||||
"chunk_length": 7,
|
||||
"length": 3,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"db3fe5357f56f6cfe9a0a34ed08e231765b423d5670741c151f7bc28cb15c4c8678df838b6ef52d74c5bb5e8c8c607b2674c024da705b558163e3127ae09f4a5c061dc6129d71755ec77b5d5a2fc088541fa612bf1273d94718e0d28b654ea9524148bf910a5c6d55b596e323d4f55ab62b0851e0985987ea39cf500bfd4d5faed37f519120b574aead76d706e149c54b6e790f7c35553f830f67553ff3f08db0f5d8a2e157f9c1ef6eedcb845a19fffd3f9c6e705b035c95f3ebe51219a91c6ffff33c52b8fd7e90417636bb443c98c3e6933b1599c09151095fff99d7af43d327fcf2afdc50144e5b8f5b1ff1f8cc8d442613dc76dd48100dd4637b38fc5fa239333c6d1e2bec2132a3e3cf5fd11f7e823fbf275071a71535740ac64de88b83ba002bd4490de5c7540e454331d46ebb825725b964ecfcc5c3bb076bf57fd819c0bd788b4495da456594503c8f5b618c4713e957a7589b151ead3a27ae80153b0fbc219f5524eec22dc91aa56ed87a71d2b6e6b857ee03a700fb5af5b23513fb73023c2764f74b40f00e44e2e7acd463e7f38c783a898015b51863659502645e7d7fdf14abf76c605d42e523a540f40e816db420d599cea502baa131d6b61b8aed86a09b9f7587e107c6fc9043d72644153b54234146535e9ec25223d293f4a2a4481b5649a7625116aef735ecbbdd9e99076985e1c424e91c29ae231c01f2b12007c81a9b3c72a84522014f4cdcb949bb9850b62b1c9c5d35f0fc3dbf4f637ae85d3082ffd15890041a455a5dd38efca02eb415afcd2c93a2b6ab46c88847f380affbc3a9af4745718044c9f23978026af66871e610e1beee21360fc5ae4f05dd32689328216db3c512fddacefb2713187f4f5069170db246ae0cb13b3b88f8c832d11ae6b26fe6f0f89b9a9056c28ac6160134ab1af4be606a2ca7d1256cfc223c823ae4921ba11aab9e4f8104885b2d17ac7826ad06b0fd0e54397e67179755b29c6d724f3e9d9a6934619ef0bfee72cdcf0031672bb6e55be53d3ef0fccf7beba7dea636eff7fdecee99f60a0bc5d5cb11e24683ca8085cf218a3607c3f5a051c33717f39834435c5c542f42bd9c9d9103173cb11436e2a626e228415924037ee4a4078f0d9a5bd0fef1dc9415740c4b32f51d199d912907a103c7e25928acadfb4dc1e8d32c34b4f0100bfe95feb850e0d7b359aae9a332913d1f8eca0d1cd93dee2f4b75076536037ca2b6bec5003ae89e03db9813d0dd2165bf50a836ca492f05750a3b5fff4d089fc54fdf225aa112d72ab021b0cef1b8d31c852133fae501406668db0cb4c3589934bde5ec218876b0dc4087b61d706234635d5d9065787a21ed895fb7c05902a554f879dae44d0905292815c5ae2338be1faa9249c7a0530623084f3a7c8bdddf0cf0123597127f9416dcad20f71bb98bf0078d9d20d4ae09c46fc1882cae650f48bebfcc443dfd7963c9944f0ce0a9bda91fe8b8f307fb3da48e573224324c35e867599262fa281ee6bc537928747dd4a1370440bda92e28eb5ba088481e476f19e2a03a7c7619eb79e2184afff7bb585319fa6a58dbfb8862f5d193ccfe0e4aeb58c1633d9e983861d4976615b11514160e5d77ed9a3e2179893c65d9de03813d27aec3485d96098764ee1e7779d47850e6b96ba064b4b913da8390416afb16719a38b725d5b27db351049bdb322cfc93a905a108d07e49764eb5f3f66fe8f3aec7580606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
10000,
|
||||
32000,
|
||||
9
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"7e6f6b02cb848e7e3c5840b05acfd699",
|
||||
"dda1902ed398efc35ebb269aa58e0d5a",
|
||||
"cd03902ade7fad281b8cfc5f1349ddf9"
|
||||
],
|
||||
[
|
||||
"f9758e4a5c3d6d2a1b4b3c7e5d397d83",
|
||||
"9bb1de90bc4c2244e630e3b6780dc86a",
|
||||
"15735600bee57d499ed0890554ef5183"
|
||||
],
|
||||
[
|
||||
"9b4106b3d83d0457705c83d147f7abe2",
|
||||
"89299140701aeef79e13f6aee1632a3b",
|
||||
"298919d5639ad48d0ea3799a98c7d082"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"429a80b8b2f73ce00d066d0c0e540cfb"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"574ce7d79da173f0652f7d1e699d5fe756c90210a093e0c893b2b7510374465c35014cdcef24d6044e63ece20db245a982c5a00f16227c6530ade1e5fd4e925f8505da8add8b97fa3216790b11b46ad76bec9b6b3f0c1e9b8284f81f0c83bb690033a6c4a8e962d34b51e27aeaa33a0d41e852a78af96c6dfba1d36364996df4eaaacc993e5633528fb0d106753112ecbfe7fec74ea75d2d1b16267ee1b3d6145e746f19d0840be93d38baa3a5c7d42c6a05311092b4fe05e38aa9e24fb9c99a5aa4bc485752d049703409ccb6656150eeb34048030f19b5353df1e23b376b1c4be2925034d8b7a847690ca7f0c4f338c30b461d9e8c1a1de094fea67efdc4d3da6e96a43cd51241f828f01028e5b0e9",
|
||||
"21c1bcbdd38fa9e8d86272f8c66c2b16768d00a79945c6014bb55374174299e4e7967f80f8df630af6f5aac52647e36437d08d0aabfd406b0984557a1a69b28f3706033ed34cde0d6bfd39a81a0fca04117cd7ac37f06815b6dc1a356454d669b0e7871238066b280f7c09e0365214235dcd39dfdf6e46ad632d50101029ff490910f79b754d99088059cf1d5da8a791b1a51d8d96fe428bac8f547dc2e9632c4e00b3a6e95d36d03d83969de2989c120aa3c54040bc7f49f910df6c5e4003721a03a3f1d743c457d0cbadbc0bd25ca7f464f404a1f39f852872314ca44ea35a32c150fc25094cd2147739d1a1e03e8f6e636170867687f1c511dbb936fb521b6639ebc145f03b6d1751fcdf14c5108e",
|
||||
"89f25b6a8ecee226a56d10e9cff57402c3198e7629d8c4152d9319172f0df07727e57ad2e170a0a32cf748f9dc0fe45597d26743a7254aebceb106f0f172a5f2aecf563787471334096bb202a07696b7e0cf22d7dda51e1cf0fcc3d0d5d0a9f4c7ea8999a3f4edb4bd7d3ecb26f2137fe9d443f34248265c25a12290866130c9ccd2dd263bce8b78c14ddbc0c94ed85da0c401ac614c789711c0e2db27ad6ef59aabfdbb6bf174fff2358c4a8d6b7e6cd2a0d41883f3563506755a920aaa7695cf35ffecb0b195d01d1d86ee1a015df5de2f145b61ef3bc5fff1634d911a69540c03444dcb256fa982b24cf064dd6e4dffe71f8d5648cf336acd9485f9d70e24f2ad6b4aa14511e7b660c0866f73672a"
|
||||
]
|
||||
],
|
||||
"public_share": "da6e96a43cd51241f828f01028e5b0e96639ebc145f03b6d1751fcdf14c5108ef2ad6b4aa14511e7b660c0866f73672a",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"db3fe5357f56f6cfe9a0a34ed08e231766b423d5670741c151f7bc28cb15c4c8688df838b6ef52d74c5bb5e8c8c607b2684c024da705b558163e3127ae09f4a5bf61dc6129d71755ec77b5d5a2fc088541fa612bf1273d94718e0d28b654ea9524148bf910a5c6d55b596e323d4f55ab63b0851e0985987ea39cf500bfd4d5faed37f519120b574aead76d706e149c54b6e790f7c35553f830f67553ff3f08db0e5d8a2e157f9c1ef6eedcb845a19fffd4f9c6e705b035c95f3ebe51219a91c6ffff33c52b8fd7e90417636bb443c98c3d6933b1599c09151095fff99d7af43d337fcf2afdc50144e5b8f5b1ff1f8cc8d442613dc76dd48100dd4637b38fc5fa249333c6d1e2bec2132a3e3cf5fd11f7e923fbf275071a71535740ac64de88b83ca002bd4490de5c7540e454331d46ebb925725b964ecfcc5c3bb076bf57fd819d0bd788b4495da456594503c8f5b618c4713e957a7589b151ead3a27ae80153b0fbc219f5524eec22dc91aa56ed87a71e2b6e6b857ee03a700fb5af5b23513fb63023c2764f74b40f00e44e2e7acd463e7f38c783a898015b51863659502645e7d7fdf14abf76c605d42e523a540f40e816db420d599cea502baa131d6b61b8add86a09b9f7587e107c6fc9043d72644053b54234146535e9ec25223d293f4a2a4481b5649a7625116aef735ecbbdd9e99076985e1c424e91c29ae231c01f2b12007c81a9b3c72a84522014f4cdcb949bb9850b62b1c9c5d35f0fc3dbf4f637af85d3082ffd15890041a455a5dd38efc902eb415afcd2c93a2b6ab46c88847f390affbc3a9af4745718044c9f23978027af66871e610e1beee21360fc5ae4f05ed32689328216db3c512fddacefb2713287f4f5069170db246ae0cb13b3b88f8d832d11ae6b26fe6f0f89b9a9056c28ad6160134ab1af4be606a2ca7d1256cfc223c823ae4921ba11aab9e4f8104885b3d17ac7826ad06b0fd0e54397e67179755b29c6d724f3e9d9a6934619ef0bfee72cdcf0031672bb6e55be53d3ef0fccf7beba7dea636eff7fdecee99f60a0bc5d5cb11e24683ca8085cf218a3607c3f5a051c33717f39834435c5c542f42bd9c9d9103173cb11436e2a626e228415924037ee4a4078f0d9a5bd0fef1dc9415740c4b32f51d199d912907a103c7e25928acadfb4dc1e8d32c34b4f0100bfe95feb850e0d7b359aae9a332913d1f8eca0d1cd93dee2f4b75076536037ca2b6bec5003ae89e03db9813d0dd2165bf50a836ca492f05750a3b5fff4d089fc54fdf225aa112d72ab021b0cef1b8d31c852133fae501406668db0cb4c3589934bde5ec218876b0dc4087b61d706234635d5d9065787a21ed895fb7c05902a554f879dae44d0905292815c5ae2338be1faa924d95673e4d904cc4215bfda1c9c0ca55fa38af6b696ef4f1a452d6870c1d82fa311cee716b00a11313a0ba7c4038e5e195b5e1d3502a44d9a9ab1636394821eaf157e6c77316f6e26b98ca81220752396890cce205581aead60bfcc3916a6c2d6d360c7e845e70c8c68e4acb5eb2877a9a7c7619eb79e2184afff7bb585319fa669b151040f5b15cab2d8c3a50379e9d9e8bf1ac6319bc32e489f64793f882d0e3e1906ac04d47eaec15c20c503d007d09d6a9b032d0f9a8b3d95447fcb1d4b7334b95d873a171f876dcc2a62a62af58e10802f88742027d3d27b9d72fea73dc84906d3dde03299dc3e033651406229da606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
19342,
|
||||
19615,
|
||||
3061
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"fc936b02cb848e7e3c5840b05acfd699",
|
||||
"7c71902ed398efc35ebb269aa58e0d5a",
|
||||
"b90f902ade7fad281b8cfc5f1349ddf9"
|
||||
],
|
||||
[
|
||||
"f9758e4a5c3d6d2a1b4b3c7e5d397d83",
|
||||
"9bb1de90bc4c2244e630e3b6780dc86a",
|
||||
"15735600bee57d499ed0890554ef5183"
|
||||
],
|
||||
[
|
||||
"9b4106b3d83d0457705c83d147f7abe2",
|
||||
"89299140701aeef79e13f6aee1632a3b",
|
||||
"298919d5639ad48d0ea3799a98c7d082"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"e129a25d4bb45ae8f5ff9d97d72f6d86"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"574ce7d79da173f0652f7d1e699d5fe7865e23ddbe20c3646ca1d41f8d0d123a831f3b90d5b917779d25ca7aafd5c903b4b996399d29d3af9fcb1c6549c36a639e45759c53b3bf6a1014fbdf7ea4d5d3726af036968d80aed52a7e48dc0a06ee66a6e34bf38ce1083cb56057cfbe98ae9138b635f2b64b60daf151ce214d33b99062b201463033142fc734e4c163fd8a5d2ea4503567c0a9739027883ab0b37ece24259b5ddcc88b3e272bbad93857a52a48abf5eb9fb135ccaf27fc0379f49f203cc0f5a4f14183ef3b935076893f0bc56dcd9b0ffbf8f711039bfd3fe894c0c007d8702db35ded99e2605fa3d9d4b70f6dfcdea9883c839e2a91aa358a38359e2d3cb20272a3ecb52e1edc17a48940",
|
||||
"21c1bcbdd38fa9e8d86272f8c66c2b167ab67945b007b46536ece1073c4ac681e7967f80f8df630af6f5aac52647e36454b87d9c2d6aa2d4c2186b47a6bef8153706033ed34cde0d6bfd39a81a0fca04618cc495486eccfbcba29099fb101871b0e7871238066b280f7c09e0365214230a741f21625c730fae5e37a7a3cbe0c00910f79b754d99088059cf1d5da8a7911221c38f8a6f79877dd34cb4fd2990744e00b3a6e95d36d03d83969de2989c12e44eb18d466e8954631aa1dbe84e78111a03a3f1d743c457d0cbadbc0bd25ca7de998de032e28d1a8ca88d584ad7a64032c150fc25094cd2147739d1a1e03e8f6e636170867687f1c511dbb936fb521b6639ebc145f03b6d1751fcdf14c5108e",
|
||||
"89f25b6a8ecee226a56d10e9cff57402a204a4e83b6b78a5aa32317f68443eac27e57ad2e170a0a32cf748f9dc0fe45524ab48c23361b4b327d498fd702f23b6aecf563787471334096bb202a07696b7eb8d79193777673f93547e14b15adb2ac7ea8999a3f4edb4bd7d3ecb26f2137f5e2881b52fd4d3ec538b978ebba54312ccd2dd263bce8b78c14ddbc0c94ed85d38fdf5fb7ee2eeb21ef066fdde8a94f89aabfdbb6bf174fff2358c4a8d6b7e6cdb080672d15b2ae06d6ca64387b56c00cf35ffecb0b195d01d1d86ee1a015df53e771738ec1faca3fcdfe4f033977dd50c03444dcb256fa982b24cf064dd6e4dffe71f8d5648cf336acd9485f9d70e24f2ad6b4aa14511e7b660c0866f73672a"
|
||||
]
|
||||
],
|
||||
"public_share": "9e2d3cb20272a3ecb52e1edc17a489406639ebc145f03b6d1751fcdf14c5108ef2ad6b4aa14511e7b660c0866f73672a",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"db3fe5357f56f6cfe9a0a34ed08e231766b423d5670741c151f7bc28cb15c4c8678df838b6ef52d74c5bb5e8c8c607b2674c024da705b558163e3127ae09f4a5c061dc6129d71755ec77b5d5a2fc088542fa612bf1273d94718e0d28b654ea9525148bf910a5c6d55b596e323d4f55ab62b0851e0985987ea39cf500bfd4d5faec37f519120b574aead76d706e149c54b6e790f7c35553f830f67553ff3f08db0f5d8a2e157f9c1ef6eedcb845a19fffd4f9c6e705b035c95f3ebe51219a91c6000034c52b8fd7e90417636bb443c98c3e6933b1599c09151095fff99d7af43d327fcf2afdc50144e5b8f5b1ff1f8cc8d442613dc76dd48100dd4637b38fc5fa249333c6d1e2bec2132a3e3cf5fd11f7e923fbf275071a71535740ac64de88b83ca002bd4490de5c7540e454331d46ebb925725b964ecfcc5c3bb076bf57fd819d0bd788b4495da456594503c8f5b618c4713e957a7589b151ead3a27ae80153b1fbc219f5524eec22dc91aa56ed87a71d2b6e6b857ee03a700fb5af5b23513fb63023c2764f74b40f00e44e2e7acd463e7f38c783a898015b51863659502645e6d7fdf14abf76c605d42e523a540f40e716db420d599cea502baa131d6b61b8add86a09b9f7587e107c6fc9043d72644153b54234146535e9ec25223d293f4a2a4481b5649a7625116aef735ecbbdd9e99076985e1c424e91c29ae231c01f2b11007c81a9b3c72a84522014f4cdcb949cb9850b62b1c9c5d35f0fc3dbf4f637af85d3082ffd15890041a455a5dd38efc902eb415afcd2c93a2b6ab46c88847f380affbc3a9af4745718044c9f23978027af66871e610e1beee21360fc5ae4f05ed32689328216db3c512fddacefb2713187f4f5069170db246ae0cb13b3b88f8d832d11ae6b26fe6f0f89b9a9056c28ac6160134ab1af4be606a2ca7d1256cfc323c823ae4921ba11aab9e4f8104885b3d17ac7826ad06b0fd0e54397e67179765b29c6d724f3e9d9a6934619ef0bfee72cdcf0031672bb6e55be53d3ef0fccf8beba7dea636eff7fdecee99f60a0bc5d5cb11e24683ca8085cf218a3607c3f5a051c33717f39834435c5c542f42bd9c9d9103173cb11436e2a626e228415924037ee4a4078f0d9a5bd0fef1dc9415740c4b32f51d199d912907a103c7e25928acadfb4dc1e8d32c34b4f0100bfe95feb850e0d7b359aae9a332913d1f8eca0d1cd93dee2f4b75076536037ca2b6bec5003ae89e03db9813d0dd2165bf50a836ca492f05750a3b5fff4d089fc54fdf225aa112d72ab021b0cef1b8d31c852133fae501406668db0cb4c3589934bde5ec218876b0dc4087b61d706234635d5d9065787a21ed895fb7c05902a554f879dae44d0905292815c5ae2338be1faa924c67468654e6880c69828616e9d011132b27aa457c6dcbd554ec4374ec882357626d6f323bfadc3b23ac6d390e40f8f2008e462458194a1f9d63e0b977f4be907f34aecb0a12ad13b95bfc858c412abab064106faf149e9b25cb557c12a54e6ae957097b8b11f174094d134cc213bf98da7c7619eb79e2184afff7bb585319fa67b935c839af760464b6f3d5402847d07d9cf6c2502ae55f33e08959b38de273b2911fa9ef530cc2cc1a1f3f8224ed7c8efe455f3ad1e462c1d089d4be054801a56ecdd4dca5bbc7191990a1c028d6d79934bf7aed757eccdd68512ebe9f919f087f6020e75fa8e281316ae3a0a50a7f5606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
15986,
|
||||
24671,
|
||||
23910
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"e0866b02cb848e7e3c5840b05acfd699",
|
||||
"3c85902ed398efc35ebb269aa58e0d5a",
|
||||
"2a61902ade7fad281b8cfc5f1349ddf9"
|
||||
],
|
||||
[
|
||||
"f9758e4a5c3d6d2a1b4b3c7e5d397d83",
|
||||
"9bb1de90bc4c2244e630e3b6780dc86a",
|
||||
"15735600bee57d499ed0890554ef5183"
|
||||
],
|
||||
[
|
||||
"9b4106b3d83d0457705c83d147f7abe2",
|
||||
"89299140701aeef79e13f6aee1632a3b",
|
||||
"298919d5639ad48d0ea3799a98c7d082"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"62b225fa36c2cbc5896a40b1360f0ce0"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"574ce7d79da173f0652f7d1e699d5fe74186663960507c6ac01fafa7046bc88a5c4146feb2861bcb9f3ad8bb294028812c631ce293cde53b6fc09c6bdbcb839ede24393da7141c26a1a594ccdab1fba7ed2b2e38faf952343a2871b854699ff9533b4f88f9bc7e935cc62e3dea6efff7e2d396d8276281db4e789dc30d3fe01c397b64d685e87e7dccae1b7636b1a1486293f29e5c3433ee211e1f66ec5a7a0f1d79ed261735f53fdb51cbd51c1a6b057bf2845e34bfa091f0f8fd7565242c8b247064dfac759c1c646d085bca6ad0845b9cc2093fd49d493ebf2d48a90b99815f0bd165f56453c6b27dff04d3a161d9fc0bc4177e423791d4064faccfbbd3218c6815a24e38fb752efc839e59043cbb",
|
||||
"21c1bcbdd38fa9e8d86272f8c66c2b16ce028e4f460022aed5c3e47011081a9ce7967f80f8df630af6f5aac52647e36481e9f91e23071ea7d98af1e76a9dd5823706033ed34cde0d6bfd39a81a0fca048271f4696baf9fd2e8a37e7b5e1be75eb0e7871238066b280f7c09e036521423abafe75c716165e86a573bab2e46efda0910f79b754d99088059cf1d5da8a79146cedb83d4b00d96b9871a66d73147984e00b3a6e95d36d03d83969de2989c12e222e1015cad12a219308643f8e1c1511a03a3f1d743c457d0cbadbc0bd25ca7cb9908430d0604df4468ab54b36f81ef32c150fc25094cd2147739d1a1e03e8f6e636170867687f1c511dbb936fb521b6639ebc145f03b6d1751fcdf14c5108e",
|
||||
"89f25b6a8ecee226a56d10e9cff5740294125c8939f32731654a11d38906f94a27e57ad2e170a0a32cf748f9dc0fe45503b71c971d945163a09158bc06295e77aecf563787471334096bb202a07696b7f7c98da9fca5e00ff5ce6eb4b9d52274c7ea8999a3f4edb4bd7d3ecb26f2137fbd6dc71ed450947219eef408d88af7dbccd2dd263bce8b78c14ddbc0c94ed85db3255ece317e82a0f3b4a873e9b72b949aabfdbb6bf174fff2358c4a8d6b7e6c545473085c7c9b5c2aa9d290b01670ffcf35ffecb0b195d01d1d86ee1a015df56465c0991dd00dfda6948958c3ff38510c03444dcb256fa982b24cf064dd6e4dffe71f8d5648cf336acd9485f9d70e24f2ad6b4aa14511e7b660c0866f73672a"
|
||||
]
|
||||
],
|
||||
"public_share": "8c6815a24e38fb752efc839e59043cbb6639ebc145f03b6d1751fcdf14c5108ef2ad6b4aa14511e7b660c0866f73672a",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": 100,
|
||||
"agg_shares": [
|
||||
"0467d4fd6a7ec85386c9f3ef0790dc10",
|
||||
"61992b02958137ac5d360c10f86f23ef"
|
||||
],
|
||||
"bits": 8,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"1ac8a54e6804d575f85957d45c728487722ad069fc1ed413da970ea56ae482d81057f898a367319a14f402d072c24bb71aa13cf4f9cdcd731e779aaa4a5d561ff40e41797cf2d43308849ff9080f846c2e78e2736a1d3cdaa68f3ec890d633cc13f5bf96466d3f02f93612bc827ff53357d52ae00dd234b9758f2cbb7aa9682d06041da1507aa12446de554a945924f445d3715279ef00f4c55ae987cec4bb9f1316efdc8737b7f924d046a6b8ef222b0dc1205ce9b464076fa80d2dfe37af4d836d597ade7d51e18e9c95d13158942d249efd0a1a226759e4bc1d46d3a41bdb227703fe0a7554cf4769935bc99cd1f35b274ecec240816af4915c7abe3e16b7be5ab5e105f9ae7b2e683191c9400cf99ab0c687e4929f87e6e64f712ca02f07a1b29fcebdbfde7655797f9c1b6b3114420d8a19736ae614116782278b7a71f9ef6928ad44ce588644886523d6fbe0b7bbb47248edbaa0b5ce33f74a07005e2a6842eb2c05778e170112f6e6a5f206d7830aa122e29069dcb4a4c064e63c29b3c6e2b22dfb5ab344ca0f1be8e8ce36d26435413de2dc4f53e158ebb8478b4a98de014a688db9470106fd7e73a65c2e656b5a627b5584ca0594ba10cc39c5612bcef576625c37c5249ad5c04e42c66d6a9653c4ec47e2bcd860870bef64f812974654f17f77c08eaa395803d33bdf31db17d76dbb9d2407d7c4f9efbce274542ff6aa0dcf188803eb586108317db430ad517ce7cb0f56d225c835161eb348949ebe253bedc338c6b939ce837561f01d7f0304963eab2a28b38c36bb169a4ee0637635818bd5e4798a8319152a2678b0aa7b837cb0f24df6148ae2c84b78db8892f4415f90f3804e7a29cdcd32a0a8625fd20aca47ee0ef12ebd6138b3534a1b42303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": 100,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"0467d4fd6a7ec85386c9f3ef0790dc10"
|
||||
],
|
||||
[
|
||||
"61992b02958137ac5d360c10f86f23ef"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"0fd2bb14ac123437f6520fdc4a817934"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"61428b8d7e326827ac832bc4074ad61652efcfdb8d95b6f06b83dd9f5d55ce9f142d1a1fd437eb8c84581ad15dcd9a57417942e63a1a46e6b0ffc8b6d6300f7d",
|
||||
"a0bd747281cd97d8377cd43bf8b529e9eb5e4b1153111bd6cd06aa3a5493a6da4470f696b9afff52ec10fc00040e4538470fdb8d3e05e188aba2b16e24c71b69"
|
||||
]
|
||||
],
|
||||
"public_share": "417942e63a1a46e6b0ffc8b6d6300f7d470fdb8d3e05e188aba2b16e24c71b69",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": 100,
|
||||
"agg_shares": [
|
||||
"b3916e4086c52aa0439356b05082885a",
|
||||
"61992b02958137ac5d360c10f86f23ef",
|
||||
"52d565bde4b89db326369d3fb70d54b6"
|
||||
],
|
||||
"bits": 8,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"ec863a16981eee70b71dc7d396a85ba412dcb4e86769d6db0c60f668456f5d6fbb844d9503580fb7b662bbb2ed7d92002e6ab4a2d31a6f611cbb5c48ca6df69811d536f74a3ff61eb29bd9b9f1b64c35eddd5c4ac97376057883a317f2989b545a682775f948f28f80f366f36b4eb90f931bca79e229eae377102295d9c46da2e239f74f045084747039c0a955726b4258bc0d14da7474bea6cd136eb5e55e9531e6a68703003a64943a5650b16674c82d9c4b526a7ed3d69f8f13ae83609cf056f3fed8d6593fdad7b367d2d248413072651073ea91b8162d42af168698f0f0928c8238b2df218e26d004d2bdb5f9f20d0a43c0286d08cfc26971f282992f82ff14d51cee3e0f3fc7411869c2176cabc6b1a68e33ff5eb217490de9f0d85cb84e9115bb7e208a190d25bf9cc138485892802a50b790ba6f45804de487a3353e54b5471adb5ab612d9ee6416649e136456215503637e0daab367149bc5cdf02a2dabc2790f84cadec1510263fe6aa27df5df395b7a241777a8ed28da27276b48f599dd895a005746cfd1f3c874e6f52407f4c417934d7091685c0b38b1d76b398ad263ec73f4f811aed38febf67a19a001a2c7ab8071f986939713cccd146c7a049c5129783359fcf86410765028fbfbbe62c2474a6b75de0ba49c037e07946deae971207f4f74b8b1d6a7b225eb0b66ed1f3878bc14d9d7a38b2162247b7ed9ac3df6fd2a98a3e4bf2855c8fb13f39487481fe03f5b5cb5123d11aaef180ff8ae69709322459a01a72e9304295ae5721d6eac6dae140677d0dd60f192f0475bacfd131d4ff3393238caa00fe0847c3a43c97a31f84f58b3c7487c5c0a09e85b39ed4b69fcdfa071da15216fd5f1fad125328e40689acce1a6cb113c2a16f599606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": 100,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"b3916e4086c52aa0439356b05082885a"
|
||||
],
|
||||
[
|
||||
"61992b02958137ac5d360c10f86f23ef"
|
||||
],
|
||||
[
|
||||
"52d565bde4b89db326369d3fb70d54b6"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"e385da3bc2246be76ff12a7093ecb45e"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"7b6a9ad01449ec86dc6736dced3ecd24b47ab2a3768908b10696d537f2b02c98cf3314686f94ac37c7d81b14fea51f784e037bbdd56b2ee8486757acad61db1e",
|
||||
"40a478cd7376c1e9ea339ddcf96ab1a7eb5e4b1153111bd6cd06aa3a5493a6da4470f696b9afff52ec10fc00040e4538470fdb8d3e05e188aba2b16e24c71b69",
|
||||
"46f1ec617740528f1c642c47185681331adc83aace0cc5ddd256cf295c93c64d207d424f5056a8d59748ba9e423c4cf5f560fb4c6505c9a773629e12f21ee230"
|
||||
]
|
||||
],
|
||||
"public_share": "4e037bbdd56b2ee8486757acad61db1e470fdb8d3e05e188aba2b16e24c71b69f560fb4c6505c9a773629e12f21ee230",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "9cb53deb2feda2f9a7f34fde29a833f4",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "9cb53deb2feda2f9a7f34fde29a833f44ade288b2f55f2cd257e5f40595b5069543b40b740dfcf8ab5c863924f4510716b625f633a2f7e55a50b24a5fec9155dec199170f9ebe46768e9d120f7e8f62840441ef53dd5d2ba2d3fd39032e2da99498f4abf815b09c667cef08f0882fa945ba3335d2c7407de1b1650a5f4fe52884caf3ef1f5802eabb8f238c4d9d419bed904dcf79b22da49f68fb547c287a9cd4a38d58017eb2031a6bf1b4defb8905c3b777e9287f62a7fb0f97e4d8a26c4e5b909958bc73a6f7512b5b845488d98a7fcedf711ada6972f4c06818d3c3e7a070a88af60dc0323b59f304935fbbbd3792e590c9b6bce7459deba3599c7f30fe64a638219dde4bde4b1a51df8d85c2f36604c44f5f188148e3ba1dca3fd8073240ee577ef322df19a13d9ffa486a6833f4eb2838a58746707b8bf531cc86098f43809276b5f02914b26cb75938ca16eafa73397920a2f5e607af30e62ff60b83e15699d4d0265affe185b307ed330941a41b2b628e44d9a19412f7d9513cacd7b1fd740b7708e3bc764a0cf2146bca7c94d1901c43f509d7dcc9dfec54476789284e53f3760610a0ac5fce205e9b9aa0355c29702a5c9395bf1de8c974c800e1037a6bf5e0bd2af7d96b7f000ff6ab93299966b6832c493b600f2595a3db99353d2f8889019cd3ec5a73fa457f5442ed5edf349e78c9cf0cbf4f65aea03754c381c3efc206b7f17447cc51ac68eceacab9d92b13b0bc700c99a26ce2b6c3271f7639aa72dc27bbd54984907abb10ef1047ef352d378ddae48bf381804c89aa1847f5027537cf6af1b30aa44cead6495e98ca5b3205d39beb49d2db6752a4e57158e8c83464002b0b4a9838bc381c1dbdc3e9a584554fb76671a15f907c0b395a5",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "87c4d0dd654bf8eec8805c68b5eb0182",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "87c4d0dd654bf8eec8805c68b5eb0182b1b8ede598cfb8d8b234038fd0492eb14268bbb2ac15a55d463c8227c2d4fae8607631d13157c4935c5d2d56e4b1e2bdfe0f80b286d82e631704acee29ab6f7acaa316d3623cc3371297604caf57bc2eafe72056143971345901b9fb9f95b6a7384c6a88143124ff693ce9e453675f87a6b6338a1e1c9f72d19e32b51f60a1d7469de1fbe25407cc338d896b34c5fc437d2551297027eeefca9aaccdb78d655a6c220cbc2d76cc4a64b04806ae893c952996abb91f6ec32b6de27fe51be59514352d31af4967c0a85c5823ff73be7f15b9c0769321e4b69cb931a4e88f9da1fde1c5df9d84a7eadb41cf25681fc64a84a1c4accded794c1e6fec1fb26a286712425bfc29521273dcfc76cbab9b3c3c2b840ab6a4f9fd73ea434fc1c22a91943ed38fef0136f0f18f680c191978ab77c750d577c3526a327564da05cfc7bb9ef52c140d9e63b1f39761648772eaa61e2efb15890aed8340e6854b428f16dff5654c8a0852d46e817b49bbe91db3c46620adbd009a0d7d40843c1b6b7786833d3c1ae097b4fa35815dbcfca78e00a34f15936ed6d0f5bf50fc25adbecd3adfa55ba6bc7052f0662595cf7a933dfcc3d0ad5d825ec3bc191586a1c36a037d1c9e73c24777825d6afe59774abdb2918c2147a0436b17bafd967e07c46c3d6240c771f4fd4f9b3fff38b294508b8af5a1b71385f90f407620b7aa636fd2b55435b3688fc26ad3c23b2ad48158c4c475c07eb58569a8d1a906452b82d582397c4c69f5e79d3082d03b4dd85b5277a8b44c933d52d168caae8c602376f5487670a172d138364cb975c569c9c2d79506746090ea8102907c91b66764fd8740ca7bd3acb59173df29b5fa7542e51bce67b97c9ee2",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"alpha": "0",
|
||||
"beta_inner": [
|
||||
[
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
[
|
||||
"2",
|
||||
"2"
|
||||
],
|
||||
[
|
||||
"3",
|
||||
"3"
|
||||
],
|
||||
[
|
||||
"4",
|
||||
"4"
|
||||
],
|
||||
[
|
||||
"5",
|
||||
"5"
|
||||
],
|
||||
[
|
||||
"6",
|
||||
"6"
|
||||
],
|
||||
[
|
||||
"7",
|
||||
"7"
|
||||
],
|
||||
[
|
||||
"8",
|
||||
"8"
|
||||
]
|
||||
],
|
||||
"beta_leaf": [
|
||||
"9",
|
||||
"9"
|
||||
],
|
||||
"binder": "736f6d65206e6f6e6365",
|
||||
"bits": 10,
|
||||
"keys": [
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"101112131415161718191a1b1c1d1e1f"
|
||||
],
|
||||
"public_share": "18850fb4933f36be2d456c4e2477baf2c9a4a7204fb09ae3e3ff925ecfe07a297b07b1980635d1e1f512afbd6388c98f5bf076cc5fe746282e59b81e51bffd6699fac7ec2dab3e9dd2c60d896beb64131d73b8abd7b2f0b327e5d91b42c677468048180e55bd80946611101ff01cb82022f7aecbe1db443499a311b7b9ee114acc16ae30d73d77ab2995eef0d536c26753647394f24d0c7b6db95b0eda08056b919e862c373e9c7a1e17590e5d5f250e56249ad28f9c13a8b57dfd7dcd05d78d49640d0aa35173cb4a659ada59f57d0c408edf52cb16d8bfb5c5d56d0c28a1aa7d96054c848cfeb0eeb6576b7c8c5328dfe502bc5eef4f1c6f58abe9ad37b448995e2b584cdb5f3a94f056ca7b868ad8f593f07c73f88596398fb4f13c5a7393b8fb0d2c76076132f54484f5f18209f42e4fe98ba2b9b1d1d19c139dc4520ada547ddbb70baecf1bba61a7b3cbb4648a7235142e201a173038dac559940a55d29a68cc87298d722b6644fa445460ddb9938c64"
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"agg_param": [
|
||||
0,
|
||||
[
|
||||
0,
|
||||
1
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"42417a6b9fd228e050220f57293f7555",
|
||||
"bfbe85945f2dd71fb2ddf0a8d5c08aaa"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f53a9af607a9ba90a1d3f318b8c32b858b3d50db495dd0cea621fc5acb48f197bd4e873a62181a039dda958c94fddf92a8c77579c03c6dfc230f22f48f76c4f904d2b114e3c8289045ca768975bbede4b411e83158149e59dcbccf8746fd6c3e46d02f6c1d55b61707cf072837674ce53",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3ff353dae51a27e776577e4452505c1be72ff784ff29b113a7d382ed46393d577cbd67fe52d4b6de1db2e204d4a6eaca3e7cee015d5fe92a830800f01375b8b9e799ac36fc76ae347a6478dad319ed9e59a21d8102ae380d8462c88d5b5bdf438b46dfec7042682ff4ac55fb9e516d1721"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"42417a6b9fd228e0",
|
||||
"50220f57293f7555"
|
||||
],
|
||||
[
|
||||
"bfbe85945f2dd71f",
|
||||
"b2ddf0a8d5c08aaa"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"f7c882b687b7bd461fb1f898356db5fa88833cdaa1e26a71",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"029b574f4e07246cb5b90e90207a148abb7dfba2efb9a32a",
|
||||
"f62d2b6738b099da6af7e90815f3a070cd054137b228c746"
|
||||
],
|
||||
[
|
||||
"264531e72e56a380",
|
||||
"dbbace18d0a95c7f"
|
||||
]
|
||||
],
|
||||
"public_share": "dfe8ba3fa8bf0b8340a577388d7f4537bc2ed02a8b8c11e498d8ffdf6eae85c76f1c8c890ad535ba72d385b77962a0a8dbb59836381fbd9d80814b2b0d95948d11ee55bcd51bece3c27a76ad9aa132f4dfe46ee0783cdf650b6276ffda3830a7f61a859d311aa38580829ef9097c0a5032d798b8a28a17869323b84f36f0e6fe82ed6bc5bff3ae8cc4d32d25ff56e9af6da83c2943b41bb4a49555dcdc76033c31ec7098db3274261f3b50d3335fc1474e",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"agg_param": [
|
||||
1,
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"f4265a0ff9c4f0d1f068b522d608c1a38cde98228531a78ccb74919ef72f5051",
|
||||
"0dd9a5f0053b0f2e11974add28f73e5c752167dd79ce5873378b6e6107d0afae"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f53a9af607a9ba90a1d3f318b8c32b858b3d50db495dd0cea621fc5acb48f197bd4e873a62181a039dda958c94fddf92a8c77579c03c6dfc230f22f48f76c4f904d2b114e3c8289045ca768975bbede4b411e83158149e59dcbccf8746fd6c3e46d02f6c1d55b61707cf072837674ce53",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3ff353dae51a27e776577e4452505c1be72ff784ff29b113a7d382ed46393d577cbd67fe52d4b6de1db2e204d4a6eaca3e7cee015d5fe92a830800f01375b8b9e799ac36fc76ae347a6478dad319ed9e59a21d8102ae380d8462c88d5b5bdf438b46dfec7042682ff4ac55fb9e516d1721"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"f4265a0ff9c4f0d1",
|
||||
"f068b522d608c1a3",
|
||||
"8cde98228531a78c",
|
||||
"cb74919ef72f5051"
|
||||
],
|
||||
[
|
||||
"0dd9a5f0053b0f2e",
|
||||
"11974add28f73e5c",
|
||||
"752167dd79ce5873",
|
||||
"378b6e6107d0afae"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"d2ca8d38065df3047d92ebacf9c366b83ad81d98fb17356a",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"4c00ed0607d7702352c8786bb90f360edd89e3c8507274b1",
|
||||
"87caa031fe8582e12bca724140b430aa5e4e3acfa9a5c0b8"
|
||||
],
|
||||
[
|
||||
"1ed0621986d79f57",
|
||||
"e32f9de6782860a8"
|
||||
]
|
||||
],
|
||||
"public_share": "dfe8ba3fa8bf0b8340a577388d7f4537bc2ed02a8b8c11e498d8ffdf6eae85c76f1c8c890ad535ba72d385b77962a0a8dbb59836381fbd9d80814b2b0d95948d11ee55bcd51bece3c27a76ad9aa132f4dfe46ee0783cdf650b6276ffda3830a7f61a859d311aa38580829ef9097c0a5032d798b8a28a17869323b84f36f0e6fe82ed6bc5bff3ae8cc4d32d25ff56e9af6da83c2943b41bb4a49555dcdc76033c31ec7098db3274261f3b50d3335fc1474e",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"agg_param": [
|
||||
2,
|
||||
[
|
||||
0,
|
||||
2,
|
||||
4,
|
||||
6
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"agg_shares": [
|
||||
"6bc200377c0ebf33de6ac488c1427b38bea3859050a09e19208319b3875c5099",
|
||||
"963dffc882f140cc23953b773dbd84c7435c7a6fae5f61e6e27ce64c77a3af66"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f53a9af607a9ba90a1d3f318b8c32b858b3d50db495dd0cea621fc5acb48f197bd4e873a62181a039dda958c94fddf92a8c77579c03c6dfc230f22f48f76c4f904d2b114e3c8289045ca768975bbede4b411e83158149e59dcbccf8746fd6c3e46d02f6c1d55b61707cf072837674ce53",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3ff353dae51a27e776577e4452505c1be72ff784ff29b113a7d382ed46393d577cbd67fe52d4b6de1db2e204d4a6eaca3e7cee015d5fe92a830800f01375b8b9e799ac36fc76ae347a6478dad319ed9e59a21d8102ae380d8462c88d5b5bdf438b46dfec7042682ff4ac55fb9e516d1721"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"6bc200377c0ebf33",
|
||||
"de6ac488c1427b38",
|
||||
"bea3859050a09e19",
|
||||
"208319b3875c5099"
|
||||
],
|
||||
[
|
||||
"963dffc882f140cc",
|
||||
"23953b773dbd84c7",
|
||||
"435c7a6fae5f61e6",
|
||||
"e27ce64c77a3af66"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"453405bb632d670892ddc291c4d886ce098d206debd7e121",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"bd7d6befff9982c88c631d4c593d754f4b817e23f0faf751",
|
||||
"89b699cb6293e43f067aa5456b9b117fbf0ba249fadce9cf"
|
||||
],
|
||||
[
|
||||
"c36085ecec965e1f",
|
||||
"3e9f7a131269a1e0"
|
||||
]
|
||||
],
|
||||
"public_share": "dfe8ba3fa8bf0b8340a577388d7f4537bc2ed02a8b8c11e498d8ffdf6eae85c76f1c8c890ad535ba72d385b77962a0a8dbb59836381fbd9d80814b2b0d95948d11ee55bcd51bece3c27a76ad9aa132f4dfe46ee0783cdf650b6276ffda3830a7f61a859d311aa38580829ef9097c0a5032d798b8a28a17869323b84f36f0e6fe82ed6bc5bff3ae8cc4d32d25ff56e9af6da83c2943b41bb4a49555dcdc76033c31ec7098db3274261f3b50d3335fc1474e",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"agg_param": [
|
||||
3,
|
||||
[
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
13,
|
||||
15
|
||||
]
|
||||
],
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"7e787b132dfe4dfcf9f8cab505a6133d30b7fd75f52a422d05ce25abe1b9cc5d3c4dce1f874d3e6bc4e9d9162ce3ae1e01da0581055c3d83de238e22b71bed1e8a69ed19cf9ccc49f2bb00c049d3153af4087218b63d6ae26ad30ca130641f50cb85fedfecf35fed0451625ebf2dac37281549b3cd8798fdd12d3eca3a68a17ec2c6f6086fca7b6dd59cd532e1b72bc95bedbfb4ce1dcc7cc873d989601e8a16ca1724e563a6c114b58e3bf58a65c621b00ebd22074223ec8e863c418a8ec83e0701d49174dab847df196325664790b6aba39c2d8ab74275b80ecc5d85c43c61",
|
||||
"6f8784ecd201b2030607354afa59ecc2cf48028a0ad5bdd2fa31da541e463322b1b231e078b2c1943b1626e9d31c51e1fe25fa7efaa3c27c21dc71dd48e41261639612e6306333b60d44ff3fb62ceac50bf78de749c2951d952cf35ecf9be02f227a0120130ca012fbae9da140d253c8d7eab64c327867022ed2c135c5975e012b3909f7903584922a632acd1e48d436a412404b31e23383378c26769fe1756924e8db1a9c593eeb4a71c40a759a39de4ff142ddf8bddc137179c3be75713741e6fe2b6e8b2547b820e69cda99b86f49545c63d27548bd8a47f133a27a3bc31e"
|
||||
],
|
||||
"bits": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"000102030405060708090a0b0c0d0e0f202122232425262728292a2b2c2d2e2f53a9af607a9ba90a1d3f318b8c32b858b3d50db495dd0cea621fc5acb48f197bd4e873a62181a039dda958c94fddf92a8c77579c03c6dfc230f22f48f76c4f904d2b114e3c8289045ca768975bbede4b411e83158149e59dcbccf8746fd6c3e46d02f6c1d55b61707cf072837674ce53",
|
||||
"101112131415161718191a1b1c1d1e1f303132333435363738393a3b3c3d3e3ff353dae51a27e776577e4452505c1be72ff784ff29b113a7d382ed46393d577cbd67fe52d4b6de1db2e204d4a6eaca3e7cee015d5fe92a830800f01375b8b9e799ac36fc76ae347a6478dad319ed9e59a21d8102ae380d8462c88d5b5bdf438b46dfec7042682ff4ac55fb9e516d1721"
|
||||
],
|
||||
"measurement": 13,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"7e787b132dfe4dfcf9f8cab505a6133d30b7fd75f52a422d05ce25abe1b9cc5d",
|
||||
"3c4dce1f874d3e6bc4e9d9162ce3ae1e01da0581055c3d83de238e22b71bed1e",
|
||||
"8a69ed19cf9ccc49f2bb00c049d3153af4087218b63d6ae26ad30ca130641f50",
|
||||
"cb85fedfecf35fed0451625ebf2dac37281549b3cd8798fdd12d3eca3a68a17e",
|
||||
"c2c6f6086fca7b6dd59cd532e1b72bc95bedbfb4ce1dcc7cc873d989601e8a16",
|
||||
"ca1724e563a6c114b58e3bf58a65c621b00ebd22074223ec8e863c418a8ec83e",
|
||||
"0701d49174dab847df196325664790b6aba39c2d8ab74275b80ecc5d85c43c61"
|
||||
],
|
||||
[
|
||||
"6f8784ecd201b2030607354afa59ecc2cf48028a0ad5bdd2fa31da541e463322",
|
||||
"b1b231e078b2c1943b1626e9d31c51e1fe25fa7efaa3c27c21dc71dd48e41261",
|
||||
"639612e6306333b60d44ff3fb62ceac50bf78de749c2951d952cf35ecf9be02f",
|
||||
"227a0120130ca012fbae9da140d253c8d7eab64c327867022ed2c135c5975e01",
|
||||
"2b3909f7903584922a632acd1e48d436a412404b31e23383378c26769fe17569",
|
||||
"24e8db1a9c593eeb4a71c40a759a39de4ff142ddf8bddc137179c3be75713741",
|
||||
"e6fe2b6e8b2547b820e69cda99b86f49545c63d27548bd8a47f133a27a3bc31e"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"d6ce08ae0327f913210f5e0701c594bf1baa15a33f6933f9b73787f73464db6a6a10f3c7e7e76a1844367d0091f16a7f090e7ed1fcc6f2a456e9e12daec41b18e08c45f8b9c5d20b02e8fecd25cb7fc05e98a6c79a1ee08da284161b3bd94d53",
|
||||
""
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"b289bbdd941be53774dbb8177fd40ee4614c325d64ca211dee7268c34fd93c7855030fd22ac1db9e4760d9cd03a090b976b2b9a9bcef2e9f9affeb5cd6afe05423b5b3db766c04dc072864e1dd8b0d0fabf8b8add732c7eeff4ae5ba5fe0fc13",
|
||||
"11454dd06e0b14dcac33a5ef81f085dbb95de345db9e11dcc9c41e34e58a9e72020de4f5bc268f79fcd5a3328d51dac5925bc42740d7c305bce9f5d0d7143b43bdd7911c4359ce2ffabf9aec473f72b1b39fed19c3eb189fa2393160dbf8503f"
|
||||
],
|
||||
[
|
||||
"b4fe321bd55f5135b7ebfda820401ad7b7fba83b65e68b8ede4b0a566a9f5629",
|
||||
"3901cde42aa0aeca48140257dfbfe528480457c49a19747121b4f5a99560a956"
|
||||
]
|
||||
],
|
||||
"public_share": "dfe8ba3fa8bf0b8340a577388d7f4537bc2ed02a8b8c11e498d8ffdf6eae85c76f1c8c890ad535ba72d385b77962a0a8dbb59836381fbd9d80814b2b0d95948d11ee55bcd51bece3c27a76ad9aa132f4dfe46ee0783cdf650b6276ffda3830a7f61a859d311aa38580829ef9097c0a5032d798b8a28a17869323b84f36f0e6fe82ed6bc5bff3ae8cc4d32d25ff56e9af6da83c2943b41bb4a49555dcdc76033c31ec7098db3274261f3b50d3335fc1474e",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -2,23 +2,23 @@
|
|||
"agg_param": null,
|
||||
"agg_result": 1,
|
||||
"agg_shares": [
|
||||
"afead111dacc0c7e",
|
||||
"53152eee2433f381"
|
||||
"352c53cbc1f95eee",
|
||||
"cdd3ac343d06a111"
|
||||
],
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"afead111dacc0c7ec08c411babd6e2404df512ddfa0a81736b7607f4ccb3f39e414fdb4bc89a63569702c92aed6a6a96",
|
||||
"352c53cbc1f95eee43253a8650e8ac18a5bd9c18b824886772947facdf1a413f1cf547cdb8c1ad4ed4c1294ccc856209",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
|
||||
],
|
||||
"measurement": 1,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"afead111dacc0c7e"
|
||||
"352c53cbc1f95eee"
|
||||
],
|
||||
[
|
||||
"53152eee2433f381"
|
||||
"cdd3ac343d06a111"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
|
@ -26,8 +26,8 @@
|
|||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"123f23c117b7ed6099be9e6a31a42a9caa60882a3b4aa50303f8b588c9efe60b",
|
||||
"efc0dc3ee748129f2da661f47a625a57d64a5b62ab38647c34bb161c7576d721"
|
||||
"f6340e6030e5960b53ad59de202314363e6063ed75a89676e3b9635d397d650e",
|
||||
"0bcbf19fce1a69f4b5de9ce10c9c671b9baa607f88bfa49de4367212193d9b3b"
|
||||
]
|
||||
],
|
||||
"public_share": "",
|
|
@ -2,14 +2,14 @@
|
|||
"agg_param": null,
|
||||
"agg_result": 1,
|
||||
"agg_shares": [
|
||||
"c5647e016eea69f6",
|
||||
"53152eee2433f381",
|
||||
"eb8553106be2a287"
|
||||
"4eeea47bcff955f0",
|
||||
"cdd3ac343d06a111",
|
||||
"e83dae4ff1ff08fe"
|
||||
],
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"c5647e016eea69f6d10e90d05e2ad8b402b8580f394a719b371ae8f1a364b280d08ca7177946a1a0b9643e2469b0a2e9",
|
||||
"4eeea47bcff955f08194b8660a6bb007a346b42952b2298158c165d94c1c40979e10b54ae7092a5a14b325df003a6f9d",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
|
||||
],
|
||||
|
@ -17,13 +17,13 @@
|
|||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"c5647e016eea69f6"
|
||||
"4eeea47bcff955f0"
|
||||
],
|
||||
[
|
||||
"53152eee2433f381"
|
||||
"cdd3ac343d06a111"
|
||||
],
|
||||
[
|
||||
"eb8553106be2a287"
|
||||
"e83dae4ff1ff08fe"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
|
@ -31,9 +31,9 @@
|
|||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"5c8d00fd24e449d375581d6adbeaf9cf4bdface6d368fd7b1562e5bf47b9fa68",
|
||||
"efc0dc3ee748129f2da661f47a625a57d64a5b62ab38647c34bb161c7576d721",
|
||||
"b7b122c4f1d2a38df764c623c266f02f7b5178c3d64735ec06037585d643f528"
|
||||
"817531f295522feac2551124114fdc827bfda7719fb1eb33b0b4e1c49761f62f",
|
||||
"0bcbf19fce1a69f4b5de9ce10c9c671b9baa607f88bfa49de4367212193d9b3b",
|
||||
"76bfdc6d999267219aa129cccf1e2459cf93ae20bf886d0d22fe0f5fcded28e6"
|
||||
]
|
||||
],
|
||||
"public_share": "",
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"ac3ba28d7f5649e6b3932251da118acf6740508adaf7837c87cd0574c48a00ea2ba59154eff2921c69cdeb23276510d3758486d91898690c4ba0fd3e6e149956",
|
||||
"55c45d7280a9b619306cddae25ee75309abfaf7525087c835c32fa8b3b75ff15d75a6eab100d6de37a3214dcd89aef2c8c7b7926e76796f3985f02c191eb66a9"
|
||||
],
|
||||
"chunk_length": 2,
|
||||
"length": 4,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"ac3ba28d7f5649e6b3932251da118acf6740508adaf7837c87cd0574c48a00ea2ba59154eff2921c69cdeb23276510d3758486d91898690c4ba0fd3e6e149956aaa0fbc70889fae40bf0b8873db6f2c2c26ef6772e0dd8d091e12a1dbe4388bbc88819a887c53a4afa8e3e35b0c00100af9000ad245790e71c322e5c252e25a25514ccc4ebeb9b9f47a98223b2d04d44f94a2cb4791ff9a056eca2a0c74ab11f08d41d917cdaa2858d372c08339c414559066eb7be61cf2b5bb36c7c598a97b19802fead02586c39b001c18b5ff36e66d9ab75d6e9c6c0c0eaae66b1014ba2645047801054acea9f87404cc2749584db303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": 2,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"ac3ba28d7f5649e6b3932251da118acf",
|
||||
"6740508adaf7837c87cd0574c48a00ea",
|
||||
"2ba59154eff2921c69cdeb23276510d3",
|
||||
"758486d91898690c4ba0fd3e6e149956"
|
||||
],
|
||||
[
|
||||
"55c45d7280a9b619306cddae25ee7530",
|
||||
"9abfaf7525087c835c32fa8b3b75ff15",
|
||||
"d75a6eab100d6de37a3214dcd89aef2c",
|
||||
"8c7b7926e76796f3985f02c191eb66a9"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"1acd91a20b79e95050d47db9bf4b1ed5"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"aaf0cada92114681d890231d05395ea51dcf30c4fa042de2f21b10d3126976a4565c5032534c5af98418b0bf0647dddada1e47da1c608f0d03070d5baf530d1e52b4ace95d26bdc41c0bf64068880a5bcbf5ab84954e1087ff8721b600477c48bc82ef4255afbf48216c910cd76ca594",
|
||||
"570f35256deeb97e0b6fdce2fac6a15a8d4d3367a586ac831119c6edeefb5ab1d4a2ad70c499a97f61b3eb86717264b1a941e67b26a189ff84bc81c89edafd3187e190bacd40bfa5813ccbd77338c7eedb90e273a045b29382cdddc5571e35de1da4a26362199818038b8624ba1ea4a9"
|
||||
]
|
||||
],
|
||||
"public_share": "bc82ef4255afbf48216c910cd76ca5941da4a26362199818038b8624ba1ea4a9",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"agg_shares": [
|
||||
"6ef23fd4b5f5502e5c215848c3703c1ac06dbc83cebd2ebb78b8549c64cf10b6a709f226d0e6aadbaac7c1512dce7f44e0715547855fae84e0a1f1fe7612423940c18ce556a3754c64b46de79038603b2ffae8c57346b7a9385f34f084d8f62d8e145aab9b0f1c038ed9f7b94d82a6cc7d32743c367987da80859005285a4b2f41e62177eead51b17bae964e100bd7408688c19870104fddb90ed31a0065a92f870079891c2ccc659a2a2cf3cb424cc3",
|
||||
"55c45d7280a9b619306cddae25ee75309abfaf7525087c835c32fa8b3b75ff15d75a6eab100d6de37a3214dcd89aef2c8c7b7926e76796f3985f02c191eb66a970fd5de8e08724782338a0d5e77d181f61a976f8712fccdde127760cb8056d105e3d2f6c325607ab4a9a3ce791283b3af006fd1a4aa66fbfb30ade0e81c5d226e5c8ad6b7e4bdd02db51d98a13f5cf81d7797d2adb9c59afef3378108eec9ad02f4bddb5208b11cdd02e159b36eddd76",
|
||||
"3e4962b9c960f8b75772ca0817a14db5a7d293060c3a55c10e15b1d75fbbef33849b9f2d1f0ce840be052ad2f996908e951231929338bb876afe0b40f701571d51411532c8d4653b5c13f242874987a5715ca0411a8a7c78c9785503c3219cc116ae76e8319adc51ef8bcb5e20551ef994c68ea87fe00866af6f91eb56e0e1a9db50301d9306d14b8dff8f26dcff583da5fdc03cb45257731ebdb4d471aebbff4cb4a9c0c24822cd5ca6be71fdcfd5c5"
|
||||
],
|
||||
"chunk_length": 3,
|
||||
"length": 11,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"6ef23fd4b5f5502e5c215848c3703c1ac06dbc83cebd2ebb78b8549c64cf10b6a709f226d0e6aadbaac7c1512dce7f44e0715547855fae84e0a1f1fe7612423940c18ce556a3754c64b46de79038603b2ffae8c57346b7a9385f34f084d8f62d8e145aab9b0f1c038ed9f7b94d82a6cc7d32743c367987da80859005285a4b2f41e62177eead51b17bae964e100bd7408688c19870104fddb90ed31a0065a92f870079891c2ccc659a2a2cf3cb424cc31d60b4e3908aa656e527d0a66eaeaaf493bde0a7a86be4ed3145a5596fab04256c95611675891b234a939c91215ec467aa9a516cd6a9a7b8d1a4ddb91e8dbfbcc8d9a45d8792f9d56a68061809b7ef4963736c20e3cb8ce6a95e1bd84c7ae51ccb14192b3101ac85a5a3a62415fb516df685b9313b53f39bc6a74062a55435f9c35f50ffd660a6d7e0e9365128bf6d87e52358afe563bc1bdce119291c611597889d36caf3247f61821eb596b089dddaf32359b12e74260a24d816335a2bf1aa93dbd84dd31773f2795ee931187525a570589f31e66a0e0d8a92370c3458fb00b2afb3e3d98f142cf9606d47d28a75caa8b4ee730e1ff3faf0aed3a154887dceaa6dfad49582d4a560b0d6599e0cbab2b36f20b8ca497f6540ca17f69595c695c2c6e0e00956acca22c71fab529936c47ad8de0e09f39d41a3b0469edcbfea242b20cd6a4748d4075ffb9a755b297902606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": 2,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"6ef23fd4b5f5502e5c215848c3703c1a",
|
||||
"c06dbc83cebd2ebb78b8549c64cf10b6",
|
||||
"a709f226d0e6aadbaac7c1512dce7f44",
|
||||
"e0715547855fae84e0a1f1fe76124239",
|
||||
"40c18ce556a3754c64b46de79038603b",
|
||||
"2ffae8c57346b7a9385f34f084d8f62d",
|
||||
"8e145aab9b0f1c038ed9f7b94d82a6cc",
|
||||
"7d32743c367987da80859005285a4b2f",
|
||||
"41e62177eead51b17bae964e100bd740",
|
||||
"8688c19870104fddb90ed31a0065a92f",
|
||||
"870079891c2ccc659a2a2cf3cb424cc3"
|
||||
],
|
||||
[
|
||||
"55c45d7280a9b619306cddae25ee7530",
|
||||
"9abfaf7525087c835c32fa8b3b75ff15",
|
||||
"d75a6eab100d6de37a3214dcd89aef2c",
|
||||
"8c7b7926e76796f3985f02c191eb66a9",
|
||||
"70fd5de8e08724782338a0d5e77d181f",
|
||||
"61a976f8712fccdde127760cb8056d10",
|
||||
"5e3d2f6c325607ab4a9a3ce791283b3a",
|
||||
"f006fd1a4aa66fbfb30ade0e81c5d226",
|
||||
"e5c8ad6b7e4bdd02db51d98a13f5cf81",
|
||||
"d7797d2adb9c59afef3378108eec9ad0",
|
||||
"2f4bddb5208b11cdd02e159b36eddd76"
|
||||
],
|
||||
[
|
||||
"3e4962b9c960f8b75772ca0817a14db5",
|
||||
"a7d293060c3a55c10e15b1d75fbbef33",
|
||||
"849b9f2d1f0ce840be052ad2f996908e",
|
||||
"951231929338bb876afe0b40f701571d",
|
||||
"51411532c8d4653b5c13f242874987a5",
|
||||
"715ca0411a8a7c78c9785503c3219cc1",
|
||||
"16ae76e8319adc51ef8bcb5e20551ef9",
|
||||
"94c68ea87fe00866af6f91eb56e0e1a9",
|
||||
"db50301d9306d14b8dff8f26dcff583d",
|
||||
"a5fdc03cb45257731ebdb4d471aebbff",
|
||||
"4cb4a9c0c24822cd5ca6be71fdcfd5c5"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"1b2dc3cedc43f65731985f19081f490a"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"cd5978e237aafb0552d6f2614be379176c256bd1bb2d3fa71ec64fcf5e64b6baf5c530e6c828d5be1468539c16917e08f6cc5d754b81f6ea05ed0747377a2dbb5a731ed05a41704a11aea67a37c668810c7fbee6ef543f6a757ffa07f22a6fdc6c37173af38746dcd7ef1f2cb0f555d13b999f3ef6a282b6649c29878349c501711da5ad2a4ac3de6fccb15c803f918a",
|
||||
"87cd13bcc0f7bb62542f40b8a480db80fca16e26264525b236a3664c792009277d9133d4ff0df494d18758677dbea683d9be082297301d1db87b6a345f74f07a3e268fd6e440eec02b3d4109b30d9c680c18d29df84586f30d30a2cf2419471d2b45845e9a4ba9f1c835ef577bcfa710e9d907592e678fa3a225e115cac914fde07e503edb901812725c6f25d7585fb2",
|
||||
"add87361075e48973dfacce50f9caa67077de5a0a3d6e85b8b04772423132387fb2732f839d0de182c65e61553e08af6fa237248acc8e6cfad227ed43c8eed56bd3c1ae929a7c2bc1c5b47dfd2d57a56fd8f3a4f2187c7f94ae1dd203aa9e3bc20a53b7ada0b4f545e0c7a8370be163a582fb321c11446cb9f3b65dc2979f432236aba9b84dbe8182bce25a97ad12186"
|
||||
]
|
||||
],
|
||||
"public_share": "711da5ad2a4ac3de6fccb15c803f918ae07e503edb901812725c6f25d7585fb2236aba9b84dbe8182bce25a97ad12186",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
256,
|
||||
257,
|
||||
258,
|
||||
259,
|
||||
260,
|
||||
261,
|
||||
262,
|
||||
263,
|
||||
264,
|
||||
265
|
||||
],
|
||||
"agg_shares": [
|
||||
"b43a2f79240602a73fafe498f4596524e2d16ccd2a68978aa0fc3b08cb757afa0e634bcf86a6f9f6066716d8d6ff6fc5d8323c1f04aa8b08948ef2e9e7a7a10e3be55e452c536f004da7d3502d93f9ef835b59067c8de2bec68afff55e15d4923cdab73e57ea28b90b70d15dc110dac2ab8c34f509842b025606222ee32ce920b14cc3ccabdfc4f1f743b9ef3ca0c2b5bd715085b0d76c95daeecfad16278bb6",
|
||||
"4dc6d086dbf9fd58a4501b670ba69adb202f9332d59768754303c4f7348a8505f59db43079590609dd98e9272900903a2ccec3e0fb5574f74f710d1618585ef1ca1ba1bad3ac90ff96582cafd26c061083a5a6f983721d411d75000aa1ea2b6dcb2648c1a815d746d88f2ea23eef253d5d74cb0af67bd4fd8df9ddd11cd316df58b43c3354203b0eecbb4610c35f3d4a4d8faf7a4f28936a09113052e9d87449"
|
||||
],
|
||||
"bits": 8,
|
||||
"chunk_length": 9,
|
||||
"length": 10,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"43118698b73a59751812aa20a73ae412766ef3c4c7559adaf4f08d6d73fbe01849ac4f0da41a26f10b1709d08f56da39953a74ee5cca941b880a5857b143cdeb7065b4b8f6b13b474040cd9e5307fd42850c79e49dc4808a8bf2d976223522179142c2cce38fce9218a371029ac88597283e246464233e9d7cf7048bbe3d18d369dfb8d462dddbe94e33f7ebc07bf0cbe8ecf9e42a156f1fd2b6c434eb62813c0929e78c86cf9bcfad5d54287598c986364fcb6fbbfa0db79dc0f4c1dbaebed54201c88b9e1f93a7fcabc0137d2b6c8ec6f423d7aeeced8f7dbd4c64e7ed595b6e5d76034a16c5686a8982397ef1e882232a95e11e7377d5b758015b716472c4dfaa9021bf2f861e18507f7f8435b55a4a3c8f7357e245596c08975169be3fdf4f2bc8600e680b9013f52b67000959ce3a588caaabdedb7d6201210902695051d808571846039dc672be3d2a7d2d25137baf47f5b71d1d907c9db4d3c20045cb32bdcf9c0094bce467da04ed90e885c9e0765a41d98cc0cc454d1d97efe2255eed21c3b2297d9d0717f8d46d1a016ab89afabd89620aa6090d21ad7226d173f23cbdd31702582ca06b336d277c4f39903414ab2baddfa578bce3be8ba27d68651d720b8401a4ffc61c999f628cdc71c058767c63f23e8b933add17cd3e50ab8540c9ebf935b2912fa26d68e2cc9289e4f894b8d03a81b8d306cadabb209de35c980d4ceea42abc4a0581b6114c77e4cc66c01be07deb7bdb8db23df5d67398497b30ea78518ff759304b5269502f93848838ba2d3e1737aadbbcbd4cde25689fff7a738df9017a4f2986c8fe8b8ba6b6f87b4dd6ec84876ba076c31039cf59b695313060ca1dfdb288c8924ebcaddddf9d067f2be6033af80313292c03996a39281c78299d8549d12cd8427104783575ec604930ab55e288606fdeb863afbeb9df6a009694c055c34d68e19c19ef3fa851363493cdf197c201958449e57e327b15eb5e25d2d347374a85e4685b432a15f4f768fa0b180f6db9f0af65cbbcb0c137a2e12cbb0aadf81e78244e2b8855634a9d0014005d9c9209381943f019df54769b4452a47ce0f223ae52a4d28d725d97e40b37b250499508838bc8a7ccb133f7a02fbfc91fa1c27685786808ae4a45e08cf841c79f3a61b58ae87005dd4e43920089fc2bc23b8c6ac3aaf2081a14edf30a0299f3094410689ec026a8bf8ba2b1c470583987c30d5d8ca6e7ea605d0c7661dba95beef2f4b94f5306317ecfa60010d6b18c2aebb994a4559fad9f3538ef7eaaf35761f7640b807483793ed8ab3ae20672da387979a8171eb1425700e257a912e645a80739e5d494ba6d419dcd4fec13aa806fcfcc84480d7e0e676916aded6f1cf9d69f7e958dceae1edaa11b2569954b7689e647906cccbdcbc2897f139356d9c85168f08ed8990aefc891158a1b89d7c19d3c56ad2a91d3de46ada48ec6338d13efb16c4cb49acd981a044c335240ce7d1db84fde51058290cae528cc7dc5794daa652268d9e5d0fa639a8549c9fdcd3fd126f653f9b970d804fdd4f420e473a31410fe9a84fc43ae415d008ac86ca0881f737382196cd5b6dd4b8673cb515ef70c4624bea32c22a7b72c2f8e1c2fc693a4905215e10580aef647be4bd36baab91c2867bcec745bc5334ce8cda1a0d77f6bb5f1838c60904f8ba7aec00d2529e87c41702b774c6f11c632d35f477988847de39626fd7e83b07ca2de2d7dbd68d07617dc590e00684c79ff1d8ff484a31056b53b29cbe470c8bf99515d7ad2939120d3b9b9ebabfb29d0e7b77cc7bb5ab97fc44591ee036de0206b8331c99c75e8bcc50ac1cb75fec3fb640318010d3ddeaaf423d14d2d715e7cf81ee4d01ad0c0f09c66b2e0b396b93c2bc97b21a42cdafe748aa4b59c250e4639be7173f4cff260339d2797e402653a3bef19a0a17763395889c4269679f6bd0289a356eaf0f06b409d24d4c112ff8f60b9383669677635f20d8eeed5c38d9500e39dca878f578b4980f374ee556aa3458b551628ff9f110d11b7f2497195d9bf3c9557e6f3d11c05f52158aab8f6485cdecfa158e592453351f1866faed652e75b37562a4c696867a89ed8b55355c82c6b571918d3995cb6516f00742a7f0974f62ca846d1306422176a204627930693eaf08951f082629d0a5537aea1d8729693798896fb16830a7cc7b29737f29637308283d5577ee3ea54987f14e4b1b4a51a17f7426a1ea86b42db1410a05064dd773bb5dacdf49702f7cf3ee9695f82fe881ef34c52e8d46e1e415989a757ec94cdd07294a2290e19749606638ed7ab2138cb9f7769a75b169f02dded1bb93c70095ef01be80b96b0ec21588146c8a238abd2bc14a170c5a024fe683c809ff478def04de33f353111c054ff502e7fad8e768bde39cfe419373b0bd40f1ae943d61b6fb824ac689955567fb7526f05d4db0c32f0e7b76cadb917ce200edfda6065129e19fa38ba3855586913baee0bbbade97144bac9c4763c95278f90bcaaa42fbbbfac31fcba0b8291025dbfd1a3660a60cc97763672331ee7db22c0932f46dfc313e7bd60ee86b7e3b4c11b5daaf8cf3e35fcaa124ae0a05bd063ff4944364ee16326b6131422bf08803aa713c771377f5f47cc940f879b2a1763110c22867c7a704c970163b15f702757d87e6e24a4474865877352ecef45294ef3bb7ec9e45f8609da982a161f89a8a9c2a6cf56fc9e8a2d9396fccf4bdd7b8aaf370f4478cb45bd5773f2a5af3d6149b4e41e364cf87c771848716998b070fe95d1d74c9d77466eae8efe0d5a0435de53d50d562c611ed8a2145c752ea54b31101db21f2688fefac5a3df5fc8163f134e5bcfcfcb2106a642ae3e6bcbd15654f09546ccb8c48d84d3bc7d0a18900dba3d66cb02ec33303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"3c1365280c0256e2bf8fa1dda6c8210c",
|
||||
"4cf0ce9963cd8783355469ad43277e53",
|
||||
"5ccbc3ef2ce2fdfc4422b2f29caa7aec",
|
||||
"f565690aac38d90228da50a3a2e2355a",
|
||||
"c1f6746cb91b25006fe29bc5b9dbfd4f",
|
||||
"2f1e7357292ff6949783aafc745cf130",
|
||||
"c39d92bfc7f862e84f259b7440b04896",
|
||||
"932ebc51032cb90072570bba4b64f80a",
|
||||
"966e96998e4aeca59e1693fabe8aeb91",
|
||||
"9b25702c90f2ce3136faef39b2b783e7"
|
||||
],
|
||||
[
|
||||
"c5ec9ad7f3fda91d24705e225937def3",
|
||||
"b60f31669c32787caeab9652bcd881ac",
|
||||
"a7343c10d31d02039fdd4d0d63558513",
|
||||
"0f9a96f553c726fdbb25af5c5d1dcaa5",
|
||||
"44098b9346e4daff741d643a462402b0",
|
||||
"d7e18ca8d6d0096b4c7c55038ba30ecf",
|
||||
"44626d4038079d1794da648bbf4fb769",
|
||||
"75d143aefcd346ff71a8f445b49b07f5",
|
||||
"7391696671b5135a45e96c054175146e",
|
||||
"6fda8fd36f0d31cead0510c64d487c18"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"faa44093d924dc5a7a7964fd9c8ec82b"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"f9ab3aa30354eb87abdd838ca558b6cbf26345360ccb2dea7deffb9e075c54b422f03470466c54abee94d25dd57eff3a073bf64fcf5eb3d7334b815115b39e6b16ea9cd0bd90f550dd701f3bf288451f17d4c7a3adc44ef5ad49663dfa2e95250320cb7d3fa0323ddcddcdb0d628146f48f6b53badd73c5333fe30cefbca3badd9a688c628f9df7129d7283772dfa0cc630e06a2795703ee70e9a01f64d3a704df997b7b6de7335aedbab9b3a1932989f93e66bb51c72416fc7f1c54bdf6f15d04c07dd5c8c2d5abea0921c5047299cd82f633af0f04fbde479b82628f0e446e781cca6b0548eaa34d8d1e5279078afe906905aa91922bf69977a92b586541d02a80245334e5321901ea62181f121f7aaaaf89061b36b0f9eb5c9ca22ddb5d09bca32696a262178178745830d0c0dee8fcc9033f8f5c98e5f3eaa91fded998019c068644495dcc3fad1eb4b63821a23b",
|
||||
"0854c55cfcab147838227c735aa7493430369af6251b129c24fca111dc13d34678b16bc625356621f29ea8e47b665ab509578cae546f46e04b013376fc8439d5cde2eb50a36d1303c487fd8456539db6e653b588217b6b273b7b3d79de062a76332662a738cb172c781306cffa8b46f9aceaaf6b663a749763c9db91c5ebb62dd0f94a3d036b82c41b49709fe6c3815e215adf1c2ae55fd9d90f8186c07c37af26d2e0803bbda031317b76cdbcc7b6817529c92ef23b00db2243ffd4767f7c8e9d39781324cef39ddf613e24e4a6351037d62b77ff946d119fb2da47fd757e16d34aa0c53bd7d6fb53472d84ca55f554638e2529702522faa8c177d51394a89bbd4cec850ee6ff565296aad4f2cd6b9f35ad7ff7b7b494b97248e3a894dce393259fa038f067fb28655b6e18edc9a032053e900a2e3d07f7ca52461922710f91f4ec2449a30929eb714d75d9db74f3a7"
|
||||
]
|
||||
],
|
||||
"public_share": "9c068644495dcc3fad1eb4b63821a23bf4ec2449a30929eb714d75d9db74f3a7",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"44118698b73a59751812aa20a73ae412766ef3c4c7559adaf4f08d6d73fbe01849ac4f0da41a26f10b1709d08f56da39953a74ee5cca941b880a5857b143cdeb7065b4b8f6b13b474040cd9e5307fd42850c79e49dc4808a8bf2d976223522179142c2cce38fce9218a371029ac88597283e246464233e9d7cf7048bbe3d18d369dfb8d462dddbe94e33f7ebc07bf0cbe8ecf9e42a156f1fd2b6c434eb62813c0929e78c86cf9bcfad5d54287598c986364fcb6fbbfa0db79dc0f4c1dbaebed54201c88b9e1f93a7fcabc0137d2b6c8ec6f423d7aeeced8f7dbd4c64e7ed595b6e5d76034a16c5686a8982397ef1e882232a95e11e7377d5b758015b716472c4e0aa9021bf2f861e18507f7f8435b55a493c8f7357e245596c08975169be3fdf4f2bc8600e680b9013f52b67000959ce3a588caaabdedb7d6201210902695051d808571846039dc672be3d2a7d2d25137baf47f5b71d1d907c9db4d3c20045cb32bdcf9c0094bce467da04ed90e885c9e0765a41d98cc0cc454d1d97efe2255eed21c3b2297d9d0717f8d46d1a016ab899fabd89620aa6090d21ad7226d173f23cbdd31702582ca06b336d277c4f39903414ab2baddfa578bce3be8ba27d68651d720b8401a4ffc61c999f628cdc71c058767c63f23e8b933add17cd3e50ab8540c9ebf935b2912fa26d68e2cc9289e4f894b8d03a81b8d306cadabb209de35c990d4ceea42abc4a0581b6114c77e4cc66c01be07deb7bdb8db23df5d67398497a30ea78518ff759304b5269502f93848838ba2d3e1737aadbbcbd4cde25689fff7a738df9017a4f2986c8fe8b8ba6b6f87b4dd6ec84876ba076c31039cf59b695313060ca1dfdb288c8924ebcaddddf9d067f2be6033af80313292c03996a39281c78299d8549d12cd8427104783575ec604930ab55e288606fdeb863afbeb9de6a009694c055c34d68e19c19ef3fa851363493cdf197c201958449e57e327b15eb5e25d2d347374a85e4685b432a15f4f768fa0b180f6db9f0af65cbbcb0c137a2e12cbb0aadf81e78244e2b8855634a9d0014005d9c9209381943f019df54779b4452a47ce0f223ae52a4d28d725d96e40b37b250499508838bc8a7ccb133f6a02fbfc91fa1c27685786808ae4a45e08cf841c79f3a61b58ae87005dd4e43920089fc2bc23b8c6ac3aaf2081a14edf30a0299f3094410689ec026a8bf8ba2b1c470583987c30d5d8ca6e7ea605d0c7661dba95beef2f4b94f5306317ecfa60010d6b18c2aebb994a4559fad9f3538ee7eaaf35761f7640b807483793ed8ab39e20672da387979a8171eb1425700e257a912e645a80739e5d494ba6d419dcd4fec13aa806fcfcc84480d7e0e676916aded6f1cf9d69f7e958dceae1edaa11b2569954b7689e647906cccbdcbc2897f139356d9c85168f08ed8990aefc891158b1b89d7c19d3c56ad2a91d3de46ada48ec6338d13efb16c4cb49acd981a044c335240ce7d1db84fde51058290cae528cb7dc5794daa652268d9e5d0fa639a8549c9fdcd3fd126f653f9b970d804fdd4f420e473a31410fe9a84fc43ae415d008ac86ca0881f737382196cd5b6dd4b8673cb515ef70c4624bea32c22a7b72c2f8e1c2fc693a4905215e10580aef647be4bd36baab91c2867bcec745bc5334ce8cda1a0d77f6bb5f1838c60904f8ba7aebf0d2529e87c41702b774c6f11c632d35f477988847de39626fd7e83b07ca2de2d7dbd68d07617dc590e00684c79ff1d8ff484a31056b53b29cbe470c8bf99515d7ad2939120d3b9b9ebabfb29d0e7b77cc7bb5ab97fc44591ee036de0206b8331c99c75e8bcc50ac1cb75fec3fb640318010d3ddeaaf423d14d2d715e7cf81ee4d01ad0c0f09c66b2e0b396b93c2bc97b21a42cdafe748aa4b59c250e4639be7173f4cff260339d2797e402653a3bef19a0a17763395889c4269679f6bd0289a356eaf0f06b409d24d4c112ff8f60b9383669677635f20d8eeed5c38d9500e39dca878f578b4980f374ee556aa3458b551628ff9f110d11b7f2497195d9bf3c9557e6f3d11c05f52158aab8f6485cdecfa158e592453351f1866faed652e75b37562a4c696867a89ed8b55355c82c6b571918d3995cb6516f00742a7f0974f62ca846d1306422176a204627930693eaf08951f082629d0a5537aea1d8729693798896fb16830a7cc7b29737f296373045c4b3272022ca8eba72c601043d08da35f439bc7d0100d6aeb7c2a7cb74a82c9abf8982362807bed855c50ebe0e571d2624f06387b4439e7580af40033dccb657fea66e721e9b2c20cdd3dba93c3261c4ec327a89ed4007b7393820f46a60ace5876392117b97b9a358a1286944bcf0e7cf4f471d46694dc37fc670aee1d4cd7fa002020f5c7ea0bc65d0ca4e42729107abeab7a2f7b86d9f663a73485f54c4870609a0789554bd2f623176f563b8d577965464bc1d7ecca70103d13c963f741f6981cb1d83a7eb09878d39d5ec7e007d390fd93c9dba87670e981d6e21069f72602526625fd88a5cafc400b01720fccc97763672331ee7db22c0932f46dfc351a6df904c48d8a976ce693f58706d7f16ffb3c0ea860cc818c14c42c925832c041c075fd291ba417723cb6e68e5deea5716298370a7c6aae23beb7276354591e9c084351aa1ddb79d9067319c93931e5018cc62705ac5dd58f1a8b7439bf4bcff7192ee243138bc26a9a2c42eb57859751a58f04f4f83b4b673254700571cdcb66a38b1187b425df9e234484fa168dd01ab675fb38b167ec06b6b7878311fcf2f20ca9aee115b9d683375ce1dc64f98d93136680c056af071501b2b50ea4b267cab3e117c157683ba9f7a10069efa0afab0ed9ec6444ddf16d5e834834fe2e0dbd0df92d6b6c19697673837bf51d697303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"3d1365280c0256e2bf8fa1dda6c8210c",
|
||||
"4cf0ce9963cd8783355469ad43277e53",
|
||||
"5bcbc3ef2ce2fdfc4422b2f29caa7aec",
|
||||
"f365690aac38d90228da50a3a2e2355a",
|
||||
"bef6746cb91b25006fe29bc5b9dbfd4f",
|
||||
"2b1e7357292ff6949783aafc745cf130",
|
||||
"be9d92bfc7f862e84f259b7440b04896",
|
||||
"8d2ebc51032cb90072570bba4b64f80a",
|
||||
"8f6e96998e4aeca59e1693fabe8aeb91",
|
||||
"9325702c90f2ce3136faef39b2b783e7"
|
||||
],
|
||||
[
|
||||
"c5ec9ad7f3fda91d24705e225937def3",
|
||||
"b60f31669c32787caeab9652bcd881ac",
|
||||
"a7343c10d31d02039fdd4d0d63558513",
|
||||
"0f9a96f553c726fdbb25af5c5d1dcaa5",
|
||||
"44098b9346e4daff741d643a462402b0",
|
||||
"d7e18ca8d6d0096b4c7c55038ba30ecf",
|
||||
"44626d4038079d1794da648bbf4fb769",
|
||||
"75d143aefcd346ff71a8f445b49b07f5",
|
||||
"7391696671b5135a45e96c054175146e",
|
||||
"6fda8fd36f0d31cead0510c64d487c18"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"22b05b9abf6f7798c91fb089ec73d79c"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"f9ab3aa30354eb87abdd838ca558b6cba06d3c978291ea82c4c856026ce4a3cb3dec40f98bf1cf3db33e3a736043891abbb4629ed714cfb72b9a70be2083cc84c41c02e448c46154ed923d78db089e67c7bbe0ef236ecd77f99c8d5e5272f4aa0320cb7d3fa0323ddcddcdb0d628146f3a94850ce63a023fa1ec776f6082d00e5fef53097f1b9a562fe9c3c4b1d9b03a87131642b49c990eb174e205bf6d68af4248001090e9ee0c2c52614d1778ac60eaf3003e3714c6ef5c99442ad527fb434fea0dce4d6fe6cd3de25237bf75d34a3b619efbec942fe7f466c96521a9672a1b8773d0a3c0009b8020cc9719ddae7aee79d2a751e4405c17493fb96c28b9dfd90c135f76582ed5f72b0867cf2276d0aee16e5c44d6ac86eff63369b58b79fd5f34e68b4406f78664224591044c64f776d62683c1ad354cfd588c2168df20c6374a2b13433b05ee12db5fdd45070eac",
|
||||
"0854c55cfcab147838227c735aa74934a0198736b579cfe4f87a1ab05d6cecc278b16bc625356621f29ea8e47b665ab59a91a8a0b72799489818a54757992f45cde2eb50a36d1303c487fd8456539db688dec5f51c76fdade09bf05bb59d8f82332662a738cb172c781306cffa8b46f986b9544adb196632fd3464f73faa14d8d0f94a3d036b82c41b49709fe6c3815ee39a9e9f46241986e33eb72c43757e3d26d2e0803bbda031317b76cdbcc7b681efe9a68224da578206e4518bbd64e9b69d39781324cef39ddf613e24e4a6351009ef3a1ca5f6d5b556077ed9c6e12b98d34aa0c53bd7d6fb53472d84ca55f554bff591feeca2f8c458b72bc0dd4a9dc4bd4cec850ee6ff565296aad4f2cd6b9fe2ca244753a83522e0d4496a1c66cdb8259fa038f067fb28655b6e18edc9a032053e900a2e3d07f7ca52461922710f91f4ec2449a30929eb714d75d9db74f3a7"
|
||||
]
|
||||
],
|
||||
"public_share": "374a2b13433b05ee12db5fdd45070eacf4ec2449a30929eb714d75d9db74f3a7",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"44118698b73a59751812aa20a73ae412776ef3c4c7559adaf4f08d6d73fbe0184aac4f0da41a26f10b1709d08f56da39963a74ee5cca941b880a5857b143cdeb7165b4b8f6b13b474040cd9e5307fd42860c79e49dc4808a8bf2d976223522179242c2cce38fce9218a371029ac88597293e246464233e9d7cf7048bbe3d18d369dfb8d462dddbe94e33f7ebc07bf0cbe9ecf9e42a156f1fd2b6c434eb62813c0a29e78c86cf9bcfad5d54287598c986374fcb6fbbfa0db79dc0f4c1dbaebed54301c88b9e1f93a7fcabc0137d2b6c8ec7f423d7aeeced8f7dbd4c64e7ed595b6f5d76034a16c5686a8982397ef1e882242a95e11e7377d5b758015b716472c4e0aa9021bf2f861e18507f7f8435b55a4a3c8f7357e245596c08975169be3fdf502bc8600e680b9013f52b67000959ce3b588caaabdedb7d6201210902695051d908571846039dc672be3d2a7d2d25137caf47f5b71d1d907c9db4d3c20045cb33bdcf9c0094bce467da04ed90e885c9e1765a41d98cc0cc454d1d97efe2255eed21c3b2297d9d0717f8d46d1a016ab89afabd89620aa6090d21ad7226d173f23dbdd31702582ca06b336d277c4f39903514ab2baddfa578bce3be8ba27d68651e720b8401a4ffc61c999f628cdc71c059767c63f23e8b933add17cd3e50ab8541c9ebf935b2912fa26d68e2cc9289e4f994b8d03a81b8d306cadabb209de35c990d4ceea42abc4a0581b6114c77e4cc67c01be07deb7bdb8db23df5d67398497b30ea78518ff759304b5269502f93848938ba2d3e1737aadbbcbd4cde25689f007b738df9017a4f2986c8fe8b8ba6b6f97b4dd6ec84876ba076c31039cf59b696313060ca1dfdb288c8924ebcaddddf9e067f2be6033af80313292c03996a39281c78299d8549d12cd8427104783575ed604930ab55e288606fdeb863afbeb9df6a009694c055c34d68e19c19ef3fa852363493cdf197c201958449e57e327b16eb5e25d2d347374a85e4685b432a15f5f768fa0b180f6db9f0af65cbbcb0c138a2e12cbb0aadf81e78244e2b8855634b9d0014005d9c9209381943f019df54779b4452a47ce0f223ae52a4d28d725d97e40b37b250499508838bc8a7ccb133f7a02fbfc91fa1c27685786808ae4a45e18cf841c79f3a61b58ae87005dd4e43930089fc2bc23b8c6ac3aaf2081a14edf40a0299f3094410689ec026a8bf8ba2b2c470583987c30d5d8ca6e7ea605d0c7761dba95beef2f4b94f5306317ecfa60010d6b18c2aebb994a4559fad9f3538ef7eaaf35761f7640b807483793ed8ab3ae20672da387979a8171eb1425700e258a912e645a80739e5d494ba6d419dcd50ec13aa806fcfcc84480d7e0e676916aeed6f1cf9d69f7e958dceae1edaa11b2669954b7689e647906cccbdcbc2897f149356d9c85168f08ed8990aefc891158b1b89d7c19d3c56ad2a91d3de46ada48fc6338d13efb16c4cb49acd981a044c345240ce7d1db84fde51058290cae528cc7dc5794daa652268d9e5d0fa639a854ac9fdcd3fd126f653f9b970d804fdd4f520e473a31410fe9a84fc43ae415d008bc86ca0881f737382196cd5b6dd4b8674cb515ef70c4624bea32c22a7b72c2f8e1c2fc693a4905215e10580aef647be4cd36baab91c2867bcec745bc5334ce8cea1a0d77f6bb5f1838c60904f8ba7aec00d2529e87c41702b774c6f11c632d360477988847de39626fd7e83b07ca2de2e7dbd68d07617dc590e00684c79ff1d90f484a31056b53b29cbe470c8bf99515e7ad2939120d3b9b9ebabfb29d0e7b77cc7bb5ab97fc44591ee036de0206b8331c99c75e8bcc50ac1cb75fec3fb640318010d3ddeaaf423d14d2d715e7cf81ee4d01ad0c0f09c66b2e0b396b93c2bc97b21a42cdafe748aa4b59c250e4639be7173f4cff260339d2797e402653a3bef19a0a17763395889c4269679f6bd0289a356eaf0f06b409d24d4c112ff8f60b9383669677635f20d8eeed5c38d9500e39dca878f578b4980f374ee556aa3458b551628ff9f110d11b7f2497195d9bf3c9557e6f3d11c05f52158aab8f6485cdecfa158e592453351f1866faed652e75b37562a4c696867a89ed8b55355c82c6b571918d3995cb6516f00742a7f0974f62ca846d1306422176a204627930693eaf08951f082629d0a5537aea1d8729693798896fb16830a7cc7b29737f29637303d4b2d335a15f1c48ed11d7948cae1b1efcb5af7c398f535e799f58a13109605cc3afae7e08683e40b1d015cfb8de1f5ca44d2eaa0fbfa549b4aa3933de82380b81ddd451d5e44a8f7f456355dfa125c002c8c5e7b2697e33dbd5cc1ac7ac8bbdfcb08ed49999a24a72685a31cdc25e0c9a27be6eb32af2d260f6d60427108a552cbe2a99ad070aec066c78bbf260e49e7ead7646ddd80d2fd067e7361e83e23aa3df8810cb4a44ee4b1205ecc8c548c064345134bb02e081a65ade1d3ec4523448d81153fa692e852e443120c8aba426dbc11bcef30ab6de561000c5be09b10524cedfab2395b99861a6f0c7e9c820dcc97763672331ee7db22c0932f46dfc3591f66851255b173a26f12c813e393a75c279385a4ef1668e0de195f818a9553d2a096f927333e1b445c8f212b665412b3f546fc56600ff4bc71f71f3c8aedc788a14e5e6f61343cc668e4d7e8d5b22314d9727e7e216f01d26d84168b8b8cad052eed93ec12355123dbbe497b1d0f6a92472c5181623dd46fe47e576cc7e804e23f58098d06504f11e23d87debccc25206b7ab2e8a54e197ecb27785fa834700ce9dab85af30a0cb4e385e6469db3e14a8545b97d72b9b4ffec701ab993457758873ec75af28a865542c437cf00bfc8092eebbb13b15cf9b481804696904c6ffae417be85dc3e8889fc8d2bf1cc7386303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": [
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"3b1465280c0256e2bf8fa1dda6c8210c",
|
||||
"4af1ce9963cd8783355469ad43277e53",
|
||||
"59ccc3ef2ce2fdfc4422b2f29caa7aec",
|
||||
"f166690aac38d90228da50a3a2e2355a",
|
||||
"bcf7746cb91b25006fe29bc5b9dbfd4f",
|
||||
"291f7357292ff6949783aafc745cf130",
|
||||
"bc9e92bfc7f862e84f259b7440b04896",
|
||||
"8b2fbc51032cb90072570bba4b64f80a",
|
||||
"8d6f96998e4aeca59e1693fabe8aeb91",
|
||||
"9126702c90f2ce3136faef39b2b783e7"
|
||||
],
|
||||
[
|
||||
"c5ec9ad7f3fda91d24705e225937def3",
|
||||
"b60f31669c32787caeab9652bcd881ac",
|
||||
"a7343c10d31d02039fdd4d0d63558513",
|
||||
"0f9a96f553c726fdbb25af5c5d1dcaa5",
|
||||
"44098b9346e4daff741d643a462402b0",
|
||||
"d7e18ca8d6d0096b4c7c55038ba30ecf",
|
||||
"44626d4038079d1794da648bbf4fb769",
|
||||
"75d143aefcd346ff71a8f445b49b07f5",
|
||||
"7391696671b5135a45e96c054175146e",
|
||||
"6fda8fd36f0d31cead0510c64d487c18"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"4b28ca5fab189f5689d02be161fe25af"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"f9ab3aa30354eb87abdd838ca558b6cb4cd1280dfc7d2f12bcb14c5a38a5fa1e4225a50845bc43cc7276668331627f53e6d1debec49fc79a6e0a2382b73e01d1af45275c3e553e9f0df2dce1fb8adf9b7cc9862e001ad0d0059d27c68b40e998a4233df802cb98ef8c94504a86e9b0e423e0661acc82059937329f34832d079f0184e04d6aafecf62dee814f748123de797d05203e140ccc9be383de282e7d377e0e3400af264e528f66cc39c14f6b590939d50e82fe5df4fa1e0aa96c27af32a5540a1ab456284c050fdf4fc7190c71acfc9d952d03d4af955b8df3f10fc64b48f1399d22792b7b18e64c7c09d986b27c4874ee16fff4ecde9d89391d3ca98a14f95ce098c05629305bb26e0db0955be0bafa82ff2a6b48283de372c395862a636d4a9bfdd06a15405a71a1d56a5a30afa2bde6fc55d8a3386fe4bd3c08985014376e4adc53e094949d34b36f1e8b16",
|
||||
"0854c55cfcab147838227c735aa7493459da23320d129aafa331318931d85cdd78b16bc625356621f29ea8e47b665ab5d29caacc5ba36200516852c360c0a2d9cde2eb50a36d1303c487fd8456539db613567966c72ef1b9f8b8f2e93aebdc1c332662a738cb172c781306cffa8b46f908c1bfd01acb45c5c06c9ecb16265a3fd0f94a3d036b82c41b49709fe6c3815e1af0509da314c9297ca795e4487c9cc326d2e0803bbda031317b76cdbcc7b6819dd6910f3002a99c7075366ab035710a9d39781324cef39ddf613e24e4a635108fbc5c1b9dada07dd81a620426914410d34aa0c53bd7d6fb53472d84ca55f554883acb353f6718ee88b8e595fe5b9373bd4cec850ee6ff565296aad4f2cd6b9f2bdf8fd9fae82be3d2039778cad3aa16259fa038f067fb28655b6e18edc9a032053e900a2e3d07f7ca52461922710f91f4ec2449a30929eb714d75d9db74f3a7"
|
||||
]
|
||||
],
|
||||
"public_share": "14376e4adc53e094949d34b36f1e8b16f4ec2449a30929eb714d75d9db74f3a7",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": [
|
||||
45328,
|
||||
76286,
|
||||
26980
|
||||
],
|
||||
"agg_shares": [
|
||||
"447fb76d69adab4dc1990d2289325675e67772e564baab6396c6b45c58a1c5febe9c72ab66aab2aab4b588ff774cb480",
|
||||
"47e6ff190ecf95c1c1941e2b03db246104c982f459555c7d30035b353f18e8985d9e4661cd30031dc481a1afdc0df13b",
|
||||
"864b49788883bef060d1d3b273f2842916e90b2641f0f71e0136f06d684652684a2e47f3cb244a386bc8d550aba55a43"
|
||||
],
|
||||
"bits": 16,
|
||||
"chunk_length": 7,
|
||||
"length": 3,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"5d82bd1f81516122465f8a60a3209afef5a5c181fdfd80d20d280edb0ae8ccc4953eff5c0efe473d411cf4f3b2e3fd320c83c6b8f2c626a42d25f89594365561966e130ecf8a778e42ce7cca37b919eb9304560ba6a60a5e5b523f5ad397b378edff4b21af66fba2f59db74e46ffdfa077bcea50472d6e771640a71fa31dd96446a2d8ce308904ea0d94760e7f8721d1531754521de6b338a20bdc8eda1d1acb6f3407a9f6f9d6cf9ccc3696c4d3226e89cf3207643a12d8c30332a8d364c97aaee81f4dc31ad62d49506e422e146492bd92a5cc933532fbfc1ee2e8e33116414358edd4baf633cdd80856f8132124171d9a2d989d3a9cf5d1d2b27baf94a5c523cf7ae624b8fe1c8ffc2229bbeecfc18e91c8683df7c579390d8b31ca87372cb5ebbe716d0edc0fe8f10c54835396a68cbacc670eee07dffa3203f8b202dc414ccb317950b35d8f4da3f0bafe8f4b0d09b5103494ed9cf9075bfd19c47f8bdee607eccea1987b4bf6ba603e29043ef636b1b327e57adf1b29b098d4eadfebb737a5ea3558794f02b97f3611034adf002518d85e769210bb2ed2e4b4390433c55d6140ffda97a5018ee007adf5125f079bebdb6eba6c35d0504d8b7a9cbbf0bd9d57bd5b563fdc052a492a7dad4a3c782b69b711ac2969758cffc3d9089a34716517c45fbb164a6bd15a001d454dfd444becef4c4a7fdbc1aaf3b7e0983b900222674a726db2b1b155190cec29c6afefe3841924dd7b212437fb10bffc8a17cea09a97ec2dfafe897e8ad4c5418946525e0908ac8790580a47a17a8089e7b78498f2a54375778e387b0985293431e2103f51600211e6e9a3f388e53d2df072d486d4c4838d8d8601fad2bd86d51ad3a58aebc0d8f6bac048d77968b26826cf545b44f7513667ac696564df8113529415a6e467d3a9f6bda8630717be753a45b5d688bbc4b95712f3bec044eb26db66f23861bf870cfb30347361e81a451f7f17642f6cbd902e92cc063b7cd4cdffbec78cb3f1957d650f89be7798894f6594ae1965964b5968c67003b247c0e83d3cef1ba2feef4c5c59d42a3efa8309f0ec4e9497b1c5a7c6b72f341d4ce5950bd12be5b6b22f32eade71f969f4ee1c0a864741fb2b5b1ad278c5f2f27000e4237b71cc664a87c50a7088b36bab5ad5a5494d599407fda9df6c538ad53563c222d3242b635116f5246b9dd6b7aba1f5abda8fd607ba18a3155c6e6c877ba0965f4005c8f475e5116bd7f899ba48ad299e5007401e49b85abf0ad681cbad302393975d682f6fb5a0795702ada0cf559198efff5ed8a16b12d1e866545db67d13ea5b7e59557776d458f5872d20ab0a3f6c74d61345bb6cd1f2dec5ee4a8d1c96d22a7b3c8ef21c1284d0785a56143100639cbfc12d1a6582b16b4bf804f6503665f275e5de6c60aac82324be975fedb2dd651c1173635fde95660cc844d347d10f8a24586a75597b1c39e828063364e13921665af885b721addc72a72d9a23bb6aa7aa3169804cf944d523d855c97a71d723b464e3976d1264bef3c266ff630ac23753eb79ad90eb5593ce456db34e977dbb19cfb58c52cbaf4826858368c3cbd8863abb5b2b95c36a447b8a4eef73e276d8bc61be6a420a12dd507bc72ef767bf49ddc9a7dcf61290b191ca4c1444e4863f1438e480a661f860c6868256aa7390e1a5033292afdcb6da8c464298c1cf5bc86bac0ad5ee5f72219e33a356a4cc3bdefd606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
10000,
|
||||
32000,
|
||||
9
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"22c1e77978e4e319838804b62d66c7d1",
|
||||
"4eecd0a1213e3921caece61ec83597ff",
|
||||
"27112639228e3b8e913cd8ff27c4e62a"
|
||||
],
|
||||
[
|
||||
"18a2aa085a9adc958c310ab9abf3b675",
|
||||
"0243d6a6c871c929a8ab73bcbfb2a2dd",
|
||||
"75df6c20efbaab098480e08f49afa5be"
|
||||
],
|
||||
[
|
||||
"d8c36d7d2d813f50b845f19026a681b8",
|
||||
"b24d59b71550fdb45567a5247817c622",
|
||||
"6e0f6da6eeb61868ce4247708e8c7316"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"065f5893e9afb58b358f78e7ed2cc07c"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"fedaa3d68353f75a2db6a1e49b2397a2bed007840b0f6ccc5ff3d89835264b58afa1771f5d2a277b65bbc2190fcac717b4f07c6d7ac4c692ad519e8a33e6d22479dfdaa6e2d3eb787ff4c9cc9deb4638b69a422203daec5a3a9b28f4eaddda1eef0000c41066465d05570989f605ad679d3d6906a8eba159f5af3995de50bdd1068ba7c0556bbd0724ada90ce58efc5b7c24f02cbc919cdb90bd915098f1f7b4bbc85c69e091f780fd70df4abb883070d02d2e06f76874cd4496526ce4aad58adf2b97e7cfed76951b532ebde9a3518e407992b67cbc6f3ccef64065bc5c214973167fea3f7baea5bf44bc32b85e37fb1f12524e4f720b7d10547ea1b558c569220ea8f5008a9be1e061606e347c3c49",
|
||||
"cb8307fb467bb023448e58c74d159bf4ed77785c059b1bfe3c5b36ab3bb46cc6051853dd2151e2cc480d5164567c8c41df857ef182519ceaf1c704a25e6c948712d4839078fa72b1e64e8531f3e54c090d01fcc6023c8dc28300ceb5fd722c80211848dd2c787bd764b2099de3139df3e7472bf3c98fc31f1d3e09b8deaada8bb19f2941d9f4660018a051ede752680aa6d05e91c0c2feb5199be821f7eba9e3abe594acb8e9611a81294b8ed708fa93caa4f00ab2df5a298a09a7d71924a9ea0b98b57a0d21fda8ff765c0394041a9a2fce409f56e24f387aba5eec7bb507d18f623f5f376d80e762ee64ef3db152a4eaa42964a69f705f15eb77df0cf6f81589a8eaa4f01fe1b5aa656a0919ae5449",
|
||||
"39a1542e3531588156bb055416c7cd68c32c28a3ac4eed2bb0f0460d41e3634bc0746eb13013792fcc318698a96b1343b152abb747abd3245a70d95eaf31f330e9e844395897d8d5f475d4644149864ca15c31da48dce96e593075a17d4deff6ae67d137adc6f38ec943c596b6fec177e66c119988225c82ac239141c8448add3f9b5c6e59d9736159ede439854b0532d9253f45dd09cb6b800fab1308b1f265978eab94b6bf4105729f7da8eddcee387a2a1eac1c64418e342368a3478fa335500371d0434c5e6511da60302f9947e84a52c49e6dc731f79ca0543441bff7a4cd909fe76206570074fca8dd8cc511ed104a88289bd3cd4d9e34a6c9a50a03649a431dd8df92d78dd6c0d478dd93c0cb"
|
||||
]
|
||||
],
|
||||
"public_share": "220ea8f5008a9be1e061606e347c3c4989a8eaa4f01fe1b5aa656a0919ae54499a431dd8df92d78dd6c0d478dd93c0cb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"5d82bd1f81516122465f8a60a3209afef6a5c181fdfd80d20d280edb0ae8ccc4963eff5c0efe473d411cf4f3b2e3fd320d83c6b8f2c626a42d25f89594365561956e130ecf8a778e42ce7cca37b919eb9304560ba6a60a5e5b523f5ad397b378edff4b21af66fba2f59db74e46ffdfa078bcea50472d6e771640a71fa31dd96446a2d8ce308904ea0d94760e7f8721d1531754521de6b338a20bdc8eda1d1acb6e3407a9f6f9d6cf9ccc3696c4d3226e8acf3207643a12d8c30332a8d364c97aaee81f4dc31ad62d49506e422e146492bc92a5cc933532fbfc1ee2e8e33116414458edd4baf633cdd80856f8132124171d9a2d989d3a9cf5d1d2b27baf94a5c524cf7ae624b8fe1c8ffc2229bbeecfc18f91c8683df7c579390d8b31ca87372cb6ebbe716d0edc0fe8f10c54835396a68dbacc670eee07dffa3203f8b202dc414dcb317950b35d8f4da3f0bafe8f4b0d09b5103494ed9cf9075bfd19c47f8bdee607eccea1987b4bf6ba603e29043ef637b1b327e57adf1b29b098d4eadfebb736a5ea3558794f02b97f3611034adf002518d85e769210bb2ed2e4b4390433c55d6140ffda97a5018ee007adf5125f079bebdb6eba6c35d0504d8b7a9cbbf0bd9c57bd5b563fdc052a492a7dad4a3c782a69b711ac2969758cffc3d9089a34716517c45fbb164a6bd15a001d454dfd444becef4c4a7fdbc1aaf3b7e0983b900222674a726db2b1b155190cec29c6afefe3841924dd7b212437fb10bffc8a17cea19a97ec2dfafe897e8ad4c5418946525d0908ac8790580a47a17a8089e7b78499f2a54375778e387b0985293431e2104051600211e6e9a3f388e53d2df072d487d4c4838d8d8601fad2bd86d51ad3a58bebc0d8f6bac048d77968b26826cf545c44f7513667ac696564df8113529415a7e467d3a9f6bda8630717be753a45b5d688bbc4b95712f3bec044eb26db66f23961bf870cfb30347361e81a451f7f17642f6cbd902e92cc063b7cd4cdffbec78cb3f1957d650f89be7798894f6594ae1965964b5968c67003b247c0e83d3cef1ba2feef4c5c59d42a3efa8309f0ec4e9497b1c5a7c6b72f341d4ce5950bd12be5b6b22f32eade71f969f4ee1c0a864741fb2b5b1ad278c5f2f27000e4237b71cc664a87c50a7088b36bab5ad5a5494d599407fda9df6c538ad53563c222d3242b635116f5246b9dd6b7aba1f5abda8fd607ba18a3155c6e6c877ba0965f4005c8f475e5116bd7f899ba48ad299e5007401e49b85abf0ad681cbad302393975d682f6fb5a0795702ada0cf559198efff5ed8a16b12d1e866545db67d13ea5b7e59557776d458f5872d20ab0a3f6c74d61345bb6cd1f2dec5ee4a8d1c96d22a7b3c8ef21c1284d0785a56143100639cbfaddd5e94884c05ad97bdc1b9878082a47662898f549754812b390a2bb02ba487c6791eb083959499d8c22ec4b79caf467542aa89e22d69fa2bea599ce1923cb05efda49baa01b0405db15d8cbfe774cf38d520cde78b817177df5ddfdd1b7c5b164c1955aadd97a8ee58a53940041a8feb79ad90eb5593ce456db34e977dbb19e3054823c514afc4e5ca9c5a7abdf60b2ad80e66199c131e1dad4436e5289a51acb7aff16412afc36a49d37a813224bbadcfa7c6ab7e817fab68ed0be42d24ca34df61c2d8a38df8d0fe92416f131481fcc5f12eee6f2e3fa7b8035d631770c4faa15307c8f847e907b1b0ce96f9fbc1606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
19342,
|
||||
19615,
|
||||
3061
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"a0e5e77978e4e319838804b62d66c7d1",
|
||||
"edbbd0a1213e3921caece61ec83597ff",
|
||||
"131d2639228e3b8e913cd8ff27c4e62a"
|
||||
],
|
||||
[
|
||||
"18a2aa085a9adc958c310ab9abf3b675",
|
||||
"0243d6a6c871c929a8ab73bcbfb2a2dd",
|
||||
"75df6c20efbaab098480e08f49afa5be"
|
||||
],
|
||||
[
|
||||
"d8c36d7d2d813f50b845f19026a681b8",
|
||||
"b24d59b71550fdb45567a5247817c622",
|
||||
"6e0f6da6eeb61868ce4247708e8c7316"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"25034fec369564c831e89105a21ed2c7"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"fedaa3d68353f75a2db6a1e49b2397a29e8bb52fe68533a6e7518d7c431765b09d9fb09303205bd20b7bad45f8ee66e18d4ff77adffd7c0b1990ba9c1c18c0d83c70aab9194ab6e494736b7521bff256e44fb48a11052214545c4fc23b0424f8965526d4d9d8d65bb919f8e823db52d0cd97bbb67e45ed5ae83205b3c379c8b72f4220e4407e1f46c60ea678ed8d47742d82abe8cc8b00055cbeb2bf9c5cf03ee851b53b57812560f8c16902a3ca3e54d95174e928fcb415d903ba75e20b5c824ad2d32f70d2375df7fd78e3a9da48d881c81e5a3126d013776adc18fa8ffbfa1ad84cc857cabdf17c81c8f08d04e9dcf11e92808e461939e811b768e5fd98c3186d21176ab71c0fd31e38c5ce590cae",
|
||||
"cb8307fb467bb023448e58c74d159bf447187a131bca6a8f66f613129c42c481051853dd2151e2cc480d5164567c8c4164b4ac35f70fe6b64517e65804ca767a12d4839078fa72b1e64e8531f3e54c09efe5a1f7aca60dd9e174711c82596e04211848dd2c787bd764b2099de3139df35aacfef634fc7a8fd7d4cb8f68a8c4eab19f2941d9f4660018a051ede752680abcbc6d60afb6984df051b2a1940016a2abe594acb8e9611a81294b8ed708fa932e03ad037523630eff76925e1a8076900b98b57a0d21fda8ff765c0394041a9ac56ec6717034855e757728c6617c78e28f623f5f376d80e762ee64ef3db152a4eaa42964a69f705f15eb77df0cf6f81589a8eaa4f01fe1b5aa656a0919ae5449",
|
||||
"39a1542e3531588156bb055416c7cd6884463d0b107893ff1174455e3c438265c0746eb13013792fcc318698a96b1343f33bbecee2d08efabd7facd829d80dafe9e844395897d8d5f475d4644149864c3faef9fbd6b690a3750c76e3721c6667ae67d137adc6f38ec943c596b6fec17750073dadaecc860ca8ce32846d68208c3f9b5c6e59d9736159ede439854b05328ab3d8b398c8d0d7401a8718d9aad830978eab94b6bf4105729f7da8eddcee386ddf59f7d19da2437c7656a1f3d873c2500371d0434c5e6511da60302f9947e8c857cee7aa680bb0dd711dfda75fe0a0cd909fe76206570074fca8dd8cc511ed104a88289bd3cd4d9e34a6c9a50a03649a431dd8df92d78dd6c0d478dd93c0cb"
|
||||
]
|
||||
],
|
||||
"public_share": "186d21176ab71c0fd31e38c5ce590cae89a8eaa4f01fe1b5aa656a0919ae54499a431dd8df92d78dd6c0d478dd93c0cb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
},
|
||||
{
|
||||
"input_shares": [
|
||||
"5d82bd1f81516122465f8a60a3209afef6a5c181fdfd80d20d280edb0ae8ccc4953eff5c0efe473d411cf4f3b2e3fd320c83c6b8f2c626a42d25f89594365561966e130ecf8a778e42ce7cca37b919eb9404560ba6a60a5e5b523f5ad397b378eeff4b21af66fba2f59db74e46ffdfa077bcea50472d6e771640a71fa31dd96445a2d8ce308904ea0d94760e7f8721d1531754521de6b338a20bdc8eda1d1acb6f3407a9f6f9d6cf9ccc3696c4d3226e8acf3207643a12d8c30332a8d364c97aafe81f4dc31ad62d49506e422e146492bd92a5cc933532fbfc1ee2e8e33116414358edd4baf633cdd80856f8132124171d9a2d989d3a9cf5d1d2b27baf94a5c524cf7ae624b8fe1c8ffc2229bbeecfc18f91c8683df7c579390d8b31ca87372cb6ebbe716d0edc0fe8f10c54835396a68dbacc670eee07dffa3203f8b202dc414dcb317950b35d8f4da3f0bafe8f4b0d09b5103494ed9cf9075bfd19c47f8bdee707eccea1987b4bf6ba603e29043ef636b1b327e57adf1b29b098d4eadfebb736a5ea3558794f02b97f3611034adf002518d85e769210bb2ed2e4b4390433c55c6140ffda97a5018ee007adf5125f079aebdb6eba6c35d0504d8b7a9cbbf0bd9c57bd5b563fdc052a492a7dad4a3c782b69b711ac2969758cffc3d9089a34716517c45fbb164a6bd15a001d454dfd444becef4c4a7fdbc1aaf3b7e0983b900221674a726db2b1b155190cec29c6afefe4841924dd7b212437fb10bffc8a17cea19a97ec2dfafe897e8ad4c5418946525d0908ac8790580a47a17a8089e7b78498f2a54375778e387b0985293431e2104051600211e6e9a3f388e53d2df072d487d4c4838d8d8601fad2bd86d51ad3a58aebc0d8f6bac048d77968b26826cf545c44f7513667ac696564df8113529415a6e467d3a9f6bda8630717be753a45b5d788bbc4b95712f3bec044eb26db66f23961bf870cfb30347361e81a451f7f17652f6cbd902e92cc063b7cd4cdffbec78cb3f1957d650f89be7798894f6594ae1a65964b5968c67003b247c0e83d3cef1ba2feef4c5c59d42a3efa8309f0ec4e9497b1c5a7c6b72f341d4ce5950bd12be5b6b22f32eade71f969f4ee1c0a864741fb2b5b1ad278c5f2f27000e4237b71cc664a87c50a7088b36bab5ad5a5494d599407fda9df6c538ad53563c222d3242b635116f5246b9dd6b7aba1f5abda8fd607ba18a3155c6e6c877ba0965f4005c8f475e5116bd7f899ba48ad299e5007401e49b85abf0ad681cbad302393975d682f6fb5a0795702ada0cf559198efff5ed8a16b12d1e866545db67d13ea5b7e59557776d458f5872d20ab0a3f6c74d61345bb6cd1f2dec5ee4a8d1c96d22a7b3c8ef21c1284d0785a56143100639cbfc3289478e516bd187dc85011217df3d9cc14a8f70c84bbd98d3a48ee1708913c3bd3c479700f0d9a01bc20a88c2c74202d08300dd1b74ec473f59b9f837fa6643b9a7627923e328512a0d1eaaef78c6fdb44f2789df4d6fea8cd33877405fbb744d075db8e2ea1c6363e0cb892ee5f90eb79ad90eb5593ce456db34e977dbb19ceba123f684af758e4bf0d03e1c085d6d425f0fd60afacc5baab06737d4cad9c375e0928789836c34150e196aca25fe1f4092243bdf49bb57f5dab084241ba1557429036f1660bb41b101fe37f03fce0595620833807d9b175ca2db5cc2df167cc1df780e3a73ecbbfcb4950440fb6c0606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": [
|
||||
15986,
|
||||
24671,
|
||||
23910
|
||||
],
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"84d8e77978e4e319838804b62d66c7d1",
|
||||
"adcfd0a1213e3921caece61ec83597ff",
|
||||
"846e2639228e3b8e913cd8ff27c4e62a"
|
||||
],
|
||||
[
|
||||
"18a2aa085a9adc958c310ab9abf3b675",
|
||||
"0243d6a6c871c929a8ab73bcbfb2a2dd",
|
||||
"75df6c20efbaab098480e08f49afa5be"
|
||||
],
|
||||
[
|
||||
"d8c36d7d2d813f50b845f19026a681b8",
|
||||
"b24d59b71550fdb45567a5247817c622",
|
||||
"6e0f6da6eeb61868ce4247708e8c7316"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"164bb9a531ed86890f679cfee8e40bd7"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"fedaa3d68353f75a2db6a1e49b2397a2d951596ce321ca830642b1c9a71f119b750393c6c754d535696c304ff488bcc6977ced640b7644d68067fa674f608e0a5751aaca2e39d7e4f47bec846689f311124c532053e2285de1dd28c7430d205d7bef7f1ff5f36d363f8ca7cf16b9d28d7fe79342273ee2629adb1396910910d4f1243c6e17898c5de5b4e50915995e0ec6b2c92fd59cf001c32018e569d540e26a5512100c73b1dfb9e76c4865fb4c8a98d2382c1bd1bbef9cb6f8fee190a7b2c18bb9c694e107ede1966ba61589e8a1ee07c034878188043745d1a13e9d328c35ab0af3a25ad52a2941d5c87ef54e798f310d45c2a44eb9b8b484c4cf2cb11289979db009d84867e096271383f95f17",
|
||||
"cb8307fb467bb023448e58c74d159bf49f9b010f8d3342eccac47f456395810c051853dd2151e2cc480d5164567c8c41b406b0bc3e39acaada3e1565084d70c512d4839078fa72b1e64e8531f3e54c09965aa5eacbdfd1c87023b5c2c1751952211848dd2c787bd764b2099de3139df3696d74860c683106e0ba03981fd175ceb19f2941d9f4660018a051ede752680a2e4d31fc97379acf03c3454eb29d0433abe594acb8e9611a81294b8ed708fa932cd4dc5aeb67e4082571e2c1a9e2e9370b98b57a0d21fda8ff765c0394041a9abc294b2171b29cdda805a50345b159548f623f5f376d80e762ee64ef3db152a4eaa42964a69f705f15eb77df0cf6f81589a8eaa4f01fe1b5aa656a0919ae5449",
|
||||
"39a1542e3531588156bb055416c7cd68bc76b21ba7b0f0ee6be53024718f5ae0c0746eb13013792fcc318698a96b13435bf89e78f7ee3fd7e39a1fdab2ea808be9e844395897d8d5f475d4644149864c3768148cc4a96a193de9ea7fad3ee418ae67d137adc6f38ec943c596b6fec177dc960939e2aa0560144c058bc34cabcb3f9b5c6e59d9736159ede439854b053235b3543dd1ff08e9184d44c28b2e98c8978eab94b6bf4105729f7da8eddcee388df030cba4cd2df0eccbf799ad07d72e500371d0434c5e6511da60302f9947e8a9a78a25434f4d85ce460e1dc1446ea7cd909fe76206570074fca8dd8cc511ed104a88289bd3cd4d9e34a6c9a50a03649a431dd8df92d78dd6c0d478dd93c0cb"
|
||||
]
|
||||
],
|
||||
"public_share": "89979db009d84867e096271383f95f1789a8eaa4f01fe1b5aa656a0919ae54499a431dd8df92d78dd6c0d478dd93c0cb",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": 100,
|
||||
"agg_shares": [
|
||||
"f3d18d266d89cb425fd64a19a436e8bc",
|
||||
"722e72d9927634bd8429b5e65bc91743"
|
||||
],
|
||||
"bits": 8,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"6dc25550077a71c59f7020e3d0e7ac8da5809fa59c2a1c7da50f49f348a2dd8f46ac57b16cf3a153fb3aa17f19b651354b6e5e2666029f55a6e0d76f25269781bb4f7cf5e79ddd703d07a49094e878e48a68b2a4b901bceeb954375740d2385821e421c0d14a2246d80a4ef53b99eb6dac3738491e6a337c124d1bbdc0e1c752ee2e3b77c8f83cf734b152c7c93caab48127d1fcae79f5dc47d4e8f62463408f5c82435087d2a244e8b54a508f8474307003ff6d76327921cfc1b68e893f1eb8cbaf513ed61bbae3d3580c34c2dfae2ceb8a1120842f5db85c78c2f4225452a6f2b618972d56f013db62e73b92a8ec83107719d35a27f5cdc493d73a772c9f5c7bc67f4280e90dc1eadbe043546a8b5975976a00739136f5f4ab37b8d845f32db1c97a831b3a9d2d3bbec621146d5a5f8788d7e7a1958b2a9382c1d9f538b91d9582bab31f496c9ddc517ae206533a8b18e0b3854587379a3120970b0246aa13758de413cee5f99794170de0bbd7479bdf968c1db98d53b30bea4417d54c9cdcc5f5e71bd7367ad95aacfb02693f25bca1a5fd67cfb3ef6406607ecef3bbe052cab782eacce5d25f6589325d20a1d6f2d9beb14c3c89cb18d0042a5376907c057203feffcd8a36b24ecabc6fe4e0133ec68a1313b669c1771b91ffb86c284646ea5ad270c492b5d5d7a24b27655c2a715af2e797823fa97f87df42184add6f1cc26e9762159d43e9548a6a89da738a8a36159369e3aa7d3b2c25c8cf95b788bfd6293b9e66a42d3bde7b00a5822eb4f97347c91f9882d54a6279c22501ce4f3fa5ebca8fcbfd7baff84e687cb8d77b48e8b4026560d873e2b8c0529d02f3d4f1e5764e498cc9d22a5d64b50fb38edc42491e5f1571244bc6269a7fbbe64406b4303132333435363738393a3b3c3d3e3f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f"
|
||||
],
|
||||
"measurement": 100,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"f3d18d266d89cb425fd64a19a436e8bc"
|
||||
],
|
||||
[
|
||||
"722e72d9927634bd8429b5e65bc91743"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"aac7d7306c0cdbbd7e23ef394322d54a"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"5e6f31522c0cb9b5107ad0c560b6ef9a69553124df856a84affd0a814674ea325a2f1c7fc62f1838a8d7aa8d4263ac0d86243c1f5c53992219ddfef99b94f76d",
|
||||
"a390ceadd3f3464ad3852f3a9f49106571003e04a8d922570934a5812d4a8c45c1cf374cea16117767d4f4ee963acd756d42402e0f2b584af325b34eaa1615ad"
|
||||
]
|
||||
],
|
||||
"public_share": "86243c1f5c53992219ddfef99b94f76d6d42402e0f2b584af325b34eaa1615ad",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
|
||||
}
|
||||
],
|
||||
"shares": 2,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"agg_param": null,
|
||||
"agg_result": 100,
|
||||
"agg_shares": [
|
||||
"f91bcafa315d7cfa26564999203babdc",
|
||||
"722e72d9927634bd8429b5e65bc91743",
|
||||
"fbb5c32b3b2c4f481c80018083fb3ce0"
|
||||
],
|
||||
"bits": 8,
|
||||
"prep": [
|
||||
{
|
||||
"input_shares": [
|
||||
"a48f16f9472cb825154a980720bd436b62db8329758026ed40deaa18e9bccea80cc0d2e40164379e7498b61a280fa86e7080b53acd1baf84604c5270ba2e161b069c2f1187bbead120b10d073d3326c5da5edeca2a2e0322253face85a769c92155d2859b86caac4f2b25d8779b2a99de3af195b2be8a4e5923d2a566833f86a683fdd68189962ea14ca940bcae99c612ca93caf3ec9bfa9ca2bdc0adeb80dba90992e4ea878bd39e321fe43f0cc073d9b5a8f9ff7f38b333e907e510a04499dc78059a620bc2d7201e3c7a4545cb5066add82690fd25269e66e1cf4334211b5578dc556c377753a501da19da81e839e6f3b7f56724ad9ee5e6dbc0a1cdcd3fc36601586eca9a50a620ed1c8941379369ae3a72b13c11c76cbd1f69d5d5acca56da4d8567007cbba3da384aa2d73e1bfba7ff77864c3b508d5a5b69b69a0bc6c092fc84d564e8f9726686e13f32239912a8a0bd92a8849d81f30560618db3bbd7f8b14a68e8a4bb2f61db7fa471573a4bee095db799ff19407b22fd77ecd55206e85f36dabec6323d8aaea77e328a07e3ccbcb3c893f6522fd0aa39f09b79dd9167cb9bccc326e2aaf51cc0e187c46766ccbe75321deb403d470795926b6879f0398a996aa5330734a5f3fed8b0e69e3a2c8a4efcd739fbedda27ae086f7144e655cdc89b07183818b56ce01dddf691d2a57f846c77d8601b203a2caf8a9bb3ec4f340d68702bf320df74e304d2db24de0dd26a6346ccc9a65c6c24e45a31636efb0919a87c8b14c08226807807acb467c29481b03e541c3ad3b2512b89c794687f4dae6b4c5f7fef5b5c348e61cca26629f015fc7babc7e0261b477843df830057f7c69248b4493b2e7a9f5503ba3eee569fc9911b35d0dd6111e8985a42273606162636465666768696a6b6c6d6e6f",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f"
|
||||
],
|
||||
"measurement": 100,
|
||||
"nonce": "000102030405060708090a0b0c0d0e0f",
|
||||
"out_shares": [
|
||||
[
|
||||
"f91bcafa315d7cfa26564999203babdc"
|
||||
],
|
||||
[
|
||||
"722e72d9927634bd8429b5e65bc91743"
|
||||
],
|
||||
[
|
||||
"fbb5c32b3b2c4f481c80018083fb3ce0"
|
||||
]
|
||||
],
|
||||
"prep_messages": [
|
||||
"215cd3acf2c12d42b2897cb57fb420a6"
|
||||
],
|
||||
"prep_shares": [
|
||||
[
|
||||
"8a17e1ae7baf0fcb35b9d89394f8f34e5e965d98db9ffbe0867029fbbdfd7195d7fda8b597d471f0046bd4508be2e2abbf23e0b165f191b5165f0350ae251442",
|
||||
"6c98be496224df8772c21173ad6fa2b271003e04a8d922570934a5812d4a8c45c1cf374cea16117767d4f4ee963acd756d42402e0f2b584af325b34eaa1615ad",
|
||||
"0c506007222c11ad1f8415f9bd9769fe526f9e6835c5e2ce8c44b01f27cc5060c4c159a86eb48e1571437659eb32b3e8800a1a73b5ae07e45e4cc67555122b2d"
|
||||
]
|
||||
],
|
||||
"public_share": "bf23e0b165f191b5165f0350ae2514426d42402e0f2b584af325b34eaa1615ad800a1a73b5ae07e45e4cc67555122b2d",
|
||||
"rand": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
|
||||
}
|
||||
],
|
||||
"shares": 3,
|
||||
"verify_key": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "3805276060157b7376b069305303669b",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "3805276060157b7376b069305303669b92beaaa4afa982314428494ba98f3595d49e76d1301b451d6fd79c9acbe9118717cfd0d4b9ef29806b4dce298a2d6aba17d7025e7964a2d7e24a263bd79d19edb11cd1db4bc07ce0ae1a9c6d1f59233e8d7065a66ce1b123ed773e4b370c9217c7032fc805f3a13f6fe2ef6f7961bf9d20fd22b8cd544cefe8e634d9245db7813ba43f630a123dfda73b6bbad8b11a916090a7d5ba8a4d20853f3f5c8222684050a53119e829313fa8de64f92553a44aa522fc90d9ec75f80547ec9637ce60e74afd51baa1d80b549444c5f0a6283ff494698ea6ffaea65964c4e0c2f9cf72a11310000261ddc85661f5068f505d34273295be9b8549b4c6278a80794929093a17cc017cf0b0e68e32e941708cfa58b9e598ac3d5d2ab4e9b33111c9c9fbc0a3682617d0ed1a0d15c9bfb9d5fd2889d1f56dd3a7f2e61ca59b0705d35f915349ffea0341816532bbdaa6dddba42bf27d1699d9e9ef580f3686ea42d687e54a87c3e6dab4f1ee5e1185faa6b809eb1a1e940692b3ba882684e8440b73e23088411000cf77ba69777b3bfa417050f0cef6cd0c9b6e7a47ab5c3da9a0e3de6ec323aed32f4cc3f51ac719e34f0bd9b0cc617e3034581a708f4a3bba587b4b4cb91529cfd47393893c3b5cd430d0456a245b0c45d4398fe423b67faa8682c764d92c514d7e34a89abc16353e71de7d49895527e632a6163d7362549a8e9ab12277460d30d7892e0a5993a4d3922738f07892764b0ceabf280779894ced52aa7fba94100c2ec0fa1973d2b11044e6844ddcdbd59f26e1b321d02c9189414cace4abece30878ca21d198f2e61b84e7cbebb6a0ad83e2abd5bf69d7f8eed193a8e141088a4b7d41fe23a939f678ba94a1d9c9c2",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "8bac064e720bb1c413040a3f41990075",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "8bac064e720bb1c413040a3f419900750ce08494b0f4f2d95171dcf44255ef94606fd5e6ffe3735329f5550e34fe61f0d4704239c107e4beb6623e20cb2e2659662aef8409fcc162a01d2333fc8d8ee7bc31c394c88edeb5904d25bf851d30246d9bf4221a5aec6ff4cb2580dde88dfa726e21b35da18f5b1839a257482ab292615b094b092444013874fce11cbd293fc81fd9a00d1befca7b1aefa2324ad2c84a8d678b02973bd539021e18861647474211e99ccfff5e47483985b25257f83665f44ed3fbce4f5a2b20e5c54239653141f7d5132b255936d33327789e13b145362059f67bd8d5b240dfd1e525d6ac5c0bb6a5b4a0b7b7318a5e22fc91763d2eb9dbd5fd3a3665127ffa63ac5be71a0b67a5ce5ee158d902a4e3a4c580e734ee40682e471373b958853eddee1de30dda6e6f4a3e3a297a79bd7f332ce89b8f0cd50589f03b95408405df362a41f58688e1fb818deaccf36eedbabc1762215102de02125dc79450d47dc04ba88cd507bdf1690ae6c1dbb44352c29687e3f60e0d3d9ed8758aa1495f4976477bda7e3cdbf37078f615dfde8330df46aebe393a665fa3f9b906498ef59ac5a0da50ebeb91c80ac0d8ba3d9bcb4e23f37e416dbe679d633834b8351085a321314d8b0276b24de1dc41091f9bdf765f2879ef0d624927a649bb693386b5a22af2ec5b67b8298abadf1e4ffa10a794ebb9924761d08ad75b595ef11118b33a8f5e649e0b8351600be077a164c806a7ee2aba58de06177ccd18e8822d35c2d6843378f254d64e5a1ee52d9c5b3f63ae262c3d6d5b63baf4e2faf436d51d6318ac9d05cf4fe3e203b2b047bdb1b4f4f8d5645a5d59ab506afc423f3a0ae5691e7f755dc5bff3b6b4f08c61614b62f63b03ce30d35a2c0d",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"binder": "62696e64657220737472696e67",
|
||||
"derived_seed": "e826c9564c620fb63357fbee88dc9bb3de2c41764adb44bea344024e1da124c6",
|
||||
"dst": "646f6d61696e2073657061726174696f6e20746167",
|
||||
"expanded_vec_field128": "e826c9564c620fb63357fbee88dc9bb3de2c41764adb44bea344024e1da124c6172f208e79762fed92c73cea422b312860008ee80e30f31d2d87840890604f39db37983f5c3483407333cecdb1b9ea550c26bc4f2d999fda91963054c6cb35a8ad8d28ee74a48e28aa475d67124e7c4417149955e506690d62e17f0730b7d4db8a9754f80603b7720205819d26bcfe4a4663d05c98c12705ea7dc333d5746d9c8ba697bb3d5be95d26ccb73052cb8fb19edfc35eaebaa22779436d3015512c9b536003d98b04a0f46feddbff762007c377c28a04039f72657650885bd40ed37acea63facd3c33d1ecb5048641053af5b4018b0c373d9ed7440da9fc6c76666c2eb8ed2943a64bbf6dae93ac91fcc26d7225c2ae42349161522fcce0b92d209411af8566b0adbaa36a8479737017efd2c359ea43924cdf432650dcd742e358af55ff6c321d0ebaae2abf5812d58b060cc147395e8137f99db58d2c425f2704da067df3a41c0443918375c177fa53545d8190d828c6045bbe5930e4762588ea14dc0a9db6cd903216ccae968ca0b11f0ac04e4dfc69a99986841dc99c851e314c7d4b10f4ef72e1244b543465fed076a7e9f50baca4ad7dccc73bfc55310f2ae6eaeaf7ee7a4d41fec76bff3b04e67d1f83e4da59f1fcb45877adfc3e4a2b1d5e3f136131ca2a02f34bdba1c5d2dafb2178674dc002d247662497b7f5818880cff308e5222e6df0bcdf6f68ebfaa8d0551530fa00ec29646441961e33b50872ada911591e16e3021baa5e7869756d3d812a63e3c7fa2c0ec2dc4cabe11c0256829b360ad9431536ab96efbe5a364cd1c323de8fbe405a2c87b9c58e5740bfb118af0ca1a23afb4a04e9cec3b9d1e57834cbc0fa17d5d7285f1f013df05e92a7343",
|
||||
"length": 40,
|
||||
"seed": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче