Previously this was defined in the app layers, because zkgroup's
original codegen didn't support custom exception types. However, we
can now move it to a common implementation in Rust.
This is a pretty mechanical translation *except* for
- changes to the ByteArray class to account for libsignal-client
supporting fixed-size arrays in the bridge layer
- introducing the Randomness wrapper struct to manage the 32 bytes of
randomness zkgroup uses
- removing ZkGroupException in favor of SignalError, which has a new
'verificationFailed' case
Everything else replaces zkgroup's generated "ffiapi" entry points with
libsignal-client's bridge_fn entry points.
- Don't validate sizes ahead of time if the subclass calls
CheckValidContents anyway.
- Move serialize() up to ByteArray. Consequently, make ProfileKeyVersion
*not* a ByteArray, since it serializes as a string.
This is a pretty mechanical translation *except* for
- moving the RANDOM_LENGTH constant out of the obsolete Native class
(libsignal-client has its own) into a new Constants class
- replacing the mocked SecureRandom with a custom subclass; Mockito
was refusing to mock SecureRandom and honestly that's fair
- removing unused classes UUIDUtil and ZkGroupError
- updating to JUnit 4, which zkgroup's tests rely on
These APIs are designed to match the generated "simpleapi" entry
points in the original zkgroup repository, to make it easier to adapt
the existing Java, Swift, and TypeScript code to libsignal-client.
The cbindgen-generated signal_ffi.h now includes constants, so that
the fixed-size arrays used to serialize zkgroup types can use named
constants in Rust. This meant filtering out some constants that were
getting picked up but that should not be included.
Note that this commit makes references to Java exception types that
will be added in a later commit.
- FFI: still maps trivially to uint64_t, no change
- JNI: reinterpret as jlong (i64) to not lose any information
- Node: until Neon supports bigints, convert to/from a big-endian
Buffer
This will be used by zkgroup. Note that in order to print the type
correctly in C, a type `Serialized<FooBar>` will be translated to
`[u8; FOO_BAR_LEN]`, where 'FOO_BAR_LEN' has to be a constant that's
in scope.
Specifically, adding support for *references to fixed-sized arrays* as
arguments (pointer-to-fixed-size-array in C, byte[] in Java, Buffer in
Node), and fixed-sized array values as results (out-pointer-to-fixed-
sized-array in C, byte[] in Java, Buffer in Node). This will be used
for some zkgroup primitive values.
This is like signal-client-java, but also contains dylibs for Mac and
Windows for testing purposes. Gradle will automatically fetch these
artifacts from the corresponding GitHub release.
This will be used to build a "testable" signal-client-java.jar that
includes native libraries for macOS and Windows in addition to Linux.
This is something zkgroup already has; in particular it allows
developers working on the server to use the zkgroup APIs even if they
run macOS or Windows on their individual machines.
u64 can't be represented as a primitive in Java or TypeScript (and for
the latter, Neon doesn't support bigint yet). However, for timestamps
represented as milliseconds, the integer-safe range of float64 still
covers more than 285,000 years, so it's reasonably safe to use
TypeScript's 'number' or Java's 'long' to represent these
ostensibly-64-bit values. Indicate this with a new Timestamp wrapper
type in the bridge layer.
In theory we could push this new Timestamp type down to the
libsignal-protocol crate. However, the protocol itself doesn't impose
any restrictions on the timestamp fields, so I figured it was best to
put it at the bridge layer, to indicate that it's about how Signal
specifically uses these fields.
This commit paves the way for being stricter about *other* u64 values
that might want to use the full 64-bit space.
- Use displaydoc to stringify the errors, using the comments that were
already there. These go into the string descriptions for errors
exposed to the apps, which can be useful.
- Split PointDecodeError into its own type so that it's not exposed
generally.
zkgroup uses capitalization to distinguish between scalar values and
curve points, which is conventional in cryptography. However, *most*
files aren't actually doing curve-level operations, and so they don't
need to except themselves from having their names checked.
Also, add deny(unsafe_code) to zkgroup. zkgroup shouldn't need any
unsafe code; like the other crates, let's not bend that policy without
a good reason.
- Bump the version to 0.9.0, mainly so it doesn't get confused with
the original repo.
- Use the poksho in this repo and our custom 3.0.0-lizard2 branch of
curve25519-dalek (instead of a 2.0.0-based one).
- Bump the sha2 dependency to match curve25519-dalek 3.0.
- Remove the reference to the crate's ffi module.
With this, the tests pass and the benchmarks run.
This is the start of an effort to merge zkgroup into libsignal-client,
including its Java, Swift, and TypeScript wrappers. For now we'll just
concentrate on getting the Rust crate to build and pass its tests.