Compare commits

...

6 Commits

Author SHA1 Message Date
Jordan Rose
5870601d53 Update Cargo.lock to merged commit 2025-10-24 18:10:42 -07:00
Jordan Rose
be7c5d5f55 Merge remote-tracking branch 'public/main' into jrose/upstream-lizard 2025-10-24 18:09:34 -07:00
Jordan Rose
3d302cc007 Update lockfile 2025-10-23 10:23:31 -07:00
Jordan Rose
5896c26b87 Adjust zkgroup to use upstream lizard 2025-10-22 16:46:37 -07:00
Jordan Rose
06ef1fadd2 Update to curve25519-dalek 5.0
This is probably not how we'll really do it; we should update our
other digest-using crates at the same time, so we can continue using
the convenience APIs from curve25519-dalek.
2025-10-22 16:19:08 -07:00
Jordan Rose
94d394165e Mechanically replace curve25519-dalek-signal with upstream-lizard branch 2025-10-22 16:09:30 -07:00
25 changed files with 207 additions and 126 deletions

170
Cargo.lock generated
View File

@ -23,7 +23,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"crypto-common 0.1.6",
"generic-array",
]
@ -268,7 +268,7 @@ dependencies = [
"rand_core 0.9.3",
"serde",
"serde_json",
"sha2",
"sha2 0.10.9",
"snow",
"static_assertions",
"strum",
@ -428,7 +428,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
@ -440,6 +440,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-buffer"
version = "0.11.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9ef36a6fcdb072aa548f3da057640ec10859eb4e91ddf526ee648d50c76a949"
dependencies = [
"hybrid-array",
]
[[package]]
name = "block-padding"
version = "0.3.3"
@ -637,7 +646,7 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"crypto-common 0.1.6",
"inout",
"zeroize",
]
@ -756,6 +765,12 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const-oid"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e"
[[package]]
name = "const-str"
version = "0.6.4"
@ -891,6 +906,15 @@ dependencies = [
"typenum",
]
[[package]]
name = "crypto-common"
version = "0.2.0-rc.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8235645834fbc6832939736ce2f2d08192652269e11010a6240f61b908a1c6"
dependencies = [
"hybrid-array",
]
[[package]]
name = "ctr"
version = "0.9.2"
@ -903,15 +927,31 @@ dependencies = [
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
source = "git+https://github.com/signalapp/curve25519-dalek?tag=signal-curve25519-4.1.3#7c6d34756355a3566a704da84dce7b1c039a6572"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest",
"fiat-crypto",
"digest 0.10.7",
"fiat-crypto 0.2.9",
"rand_core 0.6.4",
"rustc_version",
"subtle",
"zeroize",
]
[[package]]
name = "curve25519-dalek"
version = "5.0.0-pre.1"
source = "git+https://github.com/dalek-cryptography/curve25519-dalek#b76b924080dad8bd07bc26f00bf2d4e4fc5daed1"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest 0.11.0-rc.3",
"fiat-crypto 0.3.0",
"rustc_version",
"serde",
"subtle",
"zeroize",
@ -920,7 +960,8 @@ dependencies = [
[[package]]
name = "curve25519-dalek-derive"
version = "0.1.1"
source = "git+https://github.com/signalapp/curve25519-dalek?tag=signal-curve25519-4.1.3#7c6d34756355a3566a704da84dce7b1c039a6572"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
@ -985,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976"
dependencies = [
"data-encoding",
"syn 2.0.106",
"syn 1.0.109",
]
[[package]]
@ -1003,7 +1044,7 @@ version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
"const-oid",
"const-oid 0.9.6",
"zeroize",
]
@ -1131,11 +1172,22 @@ version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"block-buffer 0.10.4",
"crypto-common 0.1.6",
"subtle",
]
[[package]]
name = "digest"
version = "0.11.0-rc.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac89f8a64533a9b0eaa73a68e424db0fb1fd6271c74cc0125336a05f090568d"
dependencies = [
"block-buffer 0.11.0-rc.5",
"const-oid 0.10.1",
"crypto-common 0.2.0-rc.4",
]
[[package]]
name = "dir-test"
version = "0.4.1"
@ -1223,10 +1275,10 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
dependencies = [
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"ed25519",
"serde",
"sha2",
"sha2 0.10.9",
"subtle",
"zeroize",
]
@ -1309,6 +1361,12 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "fiat-crypto"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24"
[[package]]
name = "find-msvc-tools"
version = "0.1.1"
@ -1735,7 +1793,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
@ -1815,6 +1873,15 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hybrid-array"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f471e0a81b2f90ffc0cb2f951ae04da57de8baa46fa99112b062a5173a5088d0"
dependencies = [
"typenum",
]
[[package]]
name = "hyper"
version = "1.7.0"
@ -2346,7 +2413,7 @@ dependencies = [
"rand 0.9.2",
"rand_core 0.9.3",
"serde",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"static_assertions",
"thiserror 2.0.16",
@ -2387,7 +2454,7 @@ dependencies = [
"prost",
"rand 0.9.2",
"scopeguard",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"signal-media",
"static_assertions",
@ -2482,7 +2549,7 @@ dependencies = [
"paste",
"rayon",
"serde",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"signal-media",
"signal-neon-futures",
@ -2521,7 +2588,7 @@ dependencies = [
"clap",
"const-str",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"derive_more 2.0.1",
"displaydoc",
"foreign-types",
@ -2529,7 +2596,7 @@ dependencies = [
"log",
"proptest",
"rand 0.9.2",
"sha2",
"sha2 0.10.9",
"subtle",
"thiserror 2.0.16",
"uuid",
@ -2598,7 +2665,7 @@ dependencies = [
"assert_matches",
"const-str",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"displaydoc",
"ed25519-dalek",
"hmac",
@ -2606,7 +2673,7 @@ dependencies = [
"proptest",
"prost",
"prost-build",
"sha2",
"sha2 0.10.9",
"test-case",
"uuid",
"zerocopy",
@ -2661,7 +2728,7 @@ dependencies = [
"serde",
"serde_json",
"serde_with",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"static_assertions",
"strum",
@ -2737,7 +2804,7 @@ dependencies = [
"scopeguard",
"serde",
"serde_json",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"snow",
"static_assertions",
@ -2911,7 +2978,7 @@ dependencies = [
"const-str",
"criterion",
"ctr",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"data-encoding-macro",
"derive-where",
"derive_more 2.0.1",
@ -2934,7 +3001,7 @@ dependencies = [
"rand_core 0.9.3",
"rayon",
"serde",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"spqr",
"subtle",
@ -2951,7 +3018,7 @@ dependencies = [
"assert_matches",
"const-str",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"displaydoc",
"hex",
"hkdf",
@ -2961,7 +3028,7 @@ dependencies = [
"protobuf-codegen",
"rand 0.9.2",
"rand_core 0.9.3",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"strum",
"subtle",
@ -3532,7 +3599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420"
dependencies = [
"pest",
"sha2",
"sha2 0.10.9",
]
[[package]]
@ -3664,11 +3731,11 @@ name = "poksho"
version = "0.7.0"
dependencies = [
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"hex",
"hmac",
"rand 0.9.2",
"sha2",
"sha2 0.10.9",
]
[[package]]
@ -4546,7 +4613,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"digest 0.10.7",
]
[[package]]
@ -4563,10 +4630,21 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"digest 0.10.7",
"sha2-asm",
]
[[package]]
name = "sha2"
version = "0.11.0-rc.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1e3878ab0f98e35b2df35fe53201d088299b41a6bb63e3e34dada2ac4abd924"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.11.0-rc.3",
]
[[package]]
name = "sha2-asm"
version = "0.6.4"
@ -4616,7 +4694,7 @@ dependencies = [
"serde",
"serde_json",
"sha1",
"sha2",
"sha2 0.10.9",
"subtle",
"thiserror 2.0.16",
]
@ -4697,11 +4775,11 @@ dependencies = [
"aes-gcm",
"blake2",
"chacha20poly1305",
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"getrandom 0.3.3",
"ring",
"rustc_version",
"sha2",
"sha2 0.10.9",
"subtle",
]
@ -4770,7 +4848,7 @@ version = "1.2.0"
source = "git+https://github.com/signalapp/SparsePostQuantumRatchet.git?tag=v1.2.0#99a759a3fd40cd9304459fb007fcf177db9ed207"
dependencies = [
"cpufeatures",
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"displaydoc",
"hax-lib 0.3.4",
"hkdf",
@ -4783,7 +4861,7 @@ dependencies = [
"prost-build",
"rand 0.9.2",
"rand_core 0.9.3",
"sha2",
"sha2 0.10.9",
"sorted-vec",
"thiserror 2.0.16",
]
@ -5419,7 +5497,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"crypto-common 0.1.6",
"subtle",
]
@ -5448,7 +5526,7 @@ dependencies = [
"base64",
"clap",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"displaydoc",
"hkdf",
"hmac",
@ -5458,7 +5536,7 @@ dependencies = [
"prost",
"prost-build",
"rand 0.9.2",
"sha2",
"sha2 0.10.9",
"signal-crypto",
"subtle",
"thiserror 2.0.16",
@ -6079,7 +6157,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
dependencies = [
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"rand_core 0.6.4",
"serde",
"zeroize",
@ -6226,7 +6304,7 @@ dependencies = [
"cfg-if",
"const-str",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"derive-where",
"displaydoc",
"hex",
@ -6235,7 +6313,7 @@ dependencies = [
"poksho",
"rayon",
"serde",
"sha2",
"sha2 0.10.9",
"subtle",
"thiserror 2.0.16",
]
@ -6251,7 +6329,7 @@ dependencies = [
"bincode",
"const-str",
"criterion",
"curve25519-dalek",
"curve25519-dalek 5.0.0-pre.1",
"derive-where",
"derive_more 2.0.1",
"displaydoc",
@ -6265,7 +6343,7 @@ dependencies = [
"rand 0.9.2",
"rayon",
"serde",
"sha2",
"sha2 0.11.0-rc.2",
"static_assertions",
"subtle",
"test-case",

View File

@ -85,7 +85,6 @@ signal-neon-futures = { path = "rust/bridge/node/futures" }
# that want to use the real things can depend on those directly.
boring-signal = { git = "https://github.com/signalapp/boring", tag = "signal-v4.18.0", package = "boring", default-features = false }
curve25519-dalek-signal = { git = 'https://github.com/signalapp/curve25519-dalek', package = "curve25519-dalek", tag = 'signal-curve25519-4.1.3' }
spqr = { git = "https://github.com/signalapp/SparsePostQuantumRatchet.git", tag = "v1.2.0" }
tokio-boring-signal = { git = "https://github.com/signalapp/boring", package = "tokio-boring", tag = "signal-v4.18.0" }
@ -118,7 +117,7 @@ clap-stdin = "0.6.0"
const-str = "0.6.2"
criterion = "0.5"
ctr = "0.9.2"
curve25519-dalek = "4.1.3"
curve25519-dalek = "5.0.0-pre.1"
data-encoding-macro = "0.1.18"
derive-where = "1.2.7"
derive_more = "2.0.0"
@ -224,7 +223,7 @@ zerocopy = "0.8.24"
boring = { git = 'https://github.com/signalapp/boring', tag = 'signal-v4.18.0' }
boring-sys = { git = 'https://github.com/signalapp/boring', tag = 'signal-v4.18.0' }
curve25519-dalek = { git = 'https://github.com/signalapp/curve25519-dalek', tag = 'signal-curve25519-4.1.3' }
curve25519-dalek = { git = 'https://github.com/dalek-cryptography/curve25519-dalek', ref = "b76b924080dad8bd07bc26f00bf2d4e4fc5daed1" }
tungstenite = { git = 'https://github.com/signalapp/tungstenite-rs', tag = 'signal-v0.27.0' }
[profile.dev.package.argon2]

View File

@ -86,7 +86,7 @@ impl PrivateKey {
}
hash1.update(&random_bytes[..]);
let r = Scalar::from_hash(hash1);
let r = Scalar::from_bytes_mod_order_wide(&hash1.finalize().into());
let cap_r = (&r * ED25519_BASEPOINT_TABLE).compress();
let mut hash = Sha512::new();
@ -96,7 +96,7 @@ impl PrivateKey {
hash.update(message_piece);
}
let h = Scalar::from_hash(hash);
let h = Scalar::from_bytes_mod_order_wide(&hash.finalize().into());
let s = (h * a) + r;
let mut result = [0u8; SIGNATURE_LENGTH];
@ -136,7 +136,7 @@ impl PrivateKey {
for message_piece in message {
hash.update(message_piece);
}
let h = Scalar::from_hash(hash);
let h = Scalar::from_bytes_mod_order_wide(&hash.finalize().into());
let cap_r_check_point = EdwardsPoint::vartime_double_scalar_mul_basepoint(
&h,

View File

@ -172,7 +172,7 @@ fn auth_commitments(
&id.to_be_bytes(),
)
})
.map(|k: [u8; 64]| Scalar::hash_from_bytes::<Sha512>(&k))
.map(|k: [u8; 64]| Scalar::from_bytes_mod_order_wide(&Sha512::digest(k).into()))
.map(|s| (s, RISTRETTO_BASEPOINT_TABLE * &s))
.collect()
}
@ -425,7 +425,8 @@ impl<'a> Restore1<'a> {
sha512.update(handshake_hash);
sha512
};
let proof_scalar_base = Scalar::from_hash(hash);
let proof_scalar_base =
Scalar::from_bytes_mod_order_wide(&hash.finalize().into());
sk * proof_scalar_base + rand
})
.map(|proof_scalar| svrb::Request4 {
@ -714,7 +715,8 @@ mod test {
handshake_hash,
]
.concat();
let scalar_hash = Scalar::hash_from_bytes::<Sha512>(&scalar_hash_bytes);
let scalar_hash =
Scalar::from_bytes_mod_order_wide(&Sha512::digest(&scalar_hash_bytes).into());
let lhs = RISTRETTO_BASEPOINT_TABLE * &auth_scalar;
let rhs = state.auth_commitment * scalar_hash + auth_point;

View File

@ -209,7 +209,7 @@ fn username_sha_scalar(nickname: &str, discriminator: u64) -> Result<Scalar, Use
hash.update(nickname.as_bytes());
hash.update([0x00]);
hash.update(discriminator.to_be_bytes());
Ok(Scalar::from_hash(hash))
Ok(Scalar::from_bytes_mod_order_wide(&hash.finalize().into()))
}
fn nickname_scalar(nickname: &str) -> Result<Scalar, UsernameError> {

View File

@ -22,13 +22,11 @@ log = { workspace = true }
poksho = { workspace = true }
zkcredential = { workspace = true, features = ["rayon"] }
# Use our fork of curve25519-dalek for zkgroup support.
curve25519-dalek-signal = { workspace = true, features = ["serde"] }
aes = { workspace = true }
aes-gcm-siv = { workspace = true }
bincode = { workspace = true }
const-str = { workspace = true }
curve25519-dalek = { workspace = true, features = ["lizard", "serde"] }
derive-where = { workspace = true }
derive_more = { workspace = true, features = ["from", "try_from"] }
displaydoc = { workspace = true }
@ -38,7 +36,8 @@ partial-default = { workspace = true, features = ["derive"] }
rand = { workspace = true }
rayon = { workspace = true }
serde = { workspace = true, features = ["derive"] }
sha2 = { workspace = true }
# sha2 = { workspace = true }
sha2 = { version = "0.11.0-rc.2" }
static_assertions = { workspace = true }
subtle = { workspace = true }
thiserror = { workspace = true }

View File

@ -15,7 +15,7 @@
//! The BackupAuthCredential has the additional constraint that it should be deterministically reproducible. Rather than a randomly
//! seeded blinding key pair, the key pair is derived from, you guessed it, the client's AEP.
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use partial_default::PartialDefault;
use poksho::ShoApi;
use serde::{Deserialize, Serialize};

View File

@ -10,7 +10,7 @@
//! - the user's ACI (provided by the chat server at issuance, passed encrypted to the calling server for verification)
//! - a timestamp, truncated to day granularity (chosen by the chat server at issuance, passed publicly to the calling server for verification)
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use partial_default::PartialDefault;
use poksho::ShoApi;
use serde::{Deserialize, Serialize};

View File

@ -95,9 +95,9 @@ impl GroupSendEndorsementsResponse {
/// it.
///
/// The `usize` in each pair must be the original index of the point.
fn sort_points(points: &mut [(usize, curve25519_dalek_signal::RistrettoPoint)]) {
fn sort_points(points: &mut [(usize, curve25519_dalek::RistrettoPoint)]) {
debug_assert!(points.iter().enumerate().all(|(i, (j, _))| i == *j));
let sort_keys = curve25519_dalek_signal::RistrettoPoint::double_and_compress_batch(
let sort_keys = curve25519_dalek::RistrettoPoint::double_and_compress_batch(
points.iter().map(|(_i, point)| point),
);
points.sort_unstable_by_key(|(i, _point)| sort_keys[*i].as_bytes());
@ -114,12 +114,11 @@ impl GroupSendEndorsementsResponse {
// Note: we could save some work here by pulling the single point we need out of the
// serialized bytes, and operating directly on that. However, we'd have to remember to
// update that if the serialization format ever changes.
let mut points_to_sign: Vec<(usize, curve25519_dalek_signal::RistrettoPoint)> =
member_ciphertexts
.into_iter()
.map(|ciphertext| ciphertext.ciphertext.as_points()[0])
.enumerate()
.collect();
let mut points_to_sign: Vec<(usize, curve25519_dalek::RistrettoPoint)> = member_ciphertexts
.into_iter()
.map(|ciphertext| ciphertext.ciphertext.as_points()[0])
.enumerate()
.collect();
Self::sort_points(&mut points_to_sign);
let endorsements = zkcredential::endorsements::EndorsementResponse::issue(
@ -198,7 +197,7 @@ impl GroupSendEndorsementsResponse {
// would be much more expensive).
// We zip the results together with a set of indexes so we can un-sort the results later.
let uid_sho_seed = crypto::uid_struct::UidStruct::seed_M1();
let mut member_points: Vec<(usize, curve25519_dalek_signal::RistrettoPoint)> = user_ids
let mut member_points: Vec<(usize, curve25519_dalek::RistrettoPoint)> = user_ids
.into_iter()
.map(|user_id| {
group_params.uid_enc_key_pair.a1
@ -259,7 +258,7 @@ impl GroupSendEndorsementsResponse {
// would be much more expensive).
// We zip the results together with a set of indexes so we can un-sort the results later.
let uid_sho_seed = crypto::uid_struct::UidStruct::seed_M1();
let mut member_points: Vec<(usize, curve25519_dalek_signal::RistrettoPoint)> = user_ids
let mut member_points: Vec<(usize, curve25519_dalek::RistrettoPoint)> = user_ids
.into_par_iter()
.map(|user_id| {
group_params.uid_enc_key_pair.a1
@ -349,18 +348,18 @@ impl GroupSendEndorsementsResponse {
/// A single endorsement, for one or multiple group members.
///
/// `Storage` is usually [`curve25519_dalek_signal::RistrettoPoint`], but the `receive` APIs on
/// `Storage` is usually [`curve25519_dalek::RistrettoPoint`], but the `receive` APIs on
/// [`GroupSendEndorsementsResponse`] produce "compressed" endorsements, since they are usually
/// immediately serialized.
#[derive(Serialize, Deserialize, PartialDefault, Clone, Copy)]
#[partial_default(bound = "Storage: curve25519_dalek_signal::traits::Identity")]
#[partial_default(bound = "Storage: curve25519_dalek::traits::Identity")]
#[derive_where(PartialEq; Storage: subtle::ConstantTimeEq)]
pub struct GroupSendEndorsement<Storage = curve25519_dalek_signal::RistrettoPoint> {
pub struct GroupSendEndorsement<Storage = curve25519_dalek::RistrettoPoint> {
reserved: ReservedByte,
endorsement: zkcredential::endorsements::Endorsement<Storage>,
}
impl Debug for GroupSendEndorsement<curve25519_dalek_signal::RistrettoPoint> {
impl Debug for GroupSendEndorsement<curve25519_dalek::RistrettoPoint> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GroupSendEndorsement")
.field("reserved", &self.reserved)
@ -369,7 +368,7 @@ impl Debug for GroupSendEndorsement<curve25519_dalek_signal::RistrettoPoint> {
}
}
impl Debug for GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistretto> {
impl Debug for GroupSendEndorsement<curve25519_dalek::ristretto::CompressedRistretto> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GroupSendEndorsement")
.field("reserved", &self.reserved)
@ -397,11 +396,11 @@ pub struct ReceivedEndorsement {
// existing memory allocation isn't sufficient anyway, and thus we're better off constructing a
// single big Vec rather than two smaller ones, especially since we have to un-permute the
// results. (It's close, though, only a 3-6% difference at the largest group sizes.)
pub compressed: GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistretto>,
pub compressed: GroupSendEndorsement<curve25519_dalek::ristretto::CompressedRistretto>,
pub decompressed: GroupSendEndorsement,
}
impl GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistretto> {
impl GroupSendEndorsement<curve25519_dalek::ristretto::CompressedRistretto> {
/// Attempts to decompress the GroupSendEndorsement.
///
/// Produces [`ZkGroupDeserializationFailure`] if the compressed storage isn't a valid
@ -411,10 +410,8 @@ impl GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistrett
/// `GroupSendEndorsement<CompressedRistretto>` and then calling `decompress`.
pub fn decompress(
self,
) -> Result<
GroupSendEndorsement<curve25519_dalek_signal::RistrettoPoint>,
ZkGroupDeserializationFailure,
> {
) -> Result<GroupSendEndorsement<curve25519_dalek::RistrettoPoint>, ZkGroupDeserializationFailure>
{
Ok(GroupSendEndorsement {
reserved: self.reserved,
endorsement: self
@ -425,14 +422,14 @@ impl GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistrett
}
}
impl GroupSendEndorsement<curve25519_dalek_signal::RistrettoPoint> {
impl GroupSendEndorsement<curve25519_dalek::RistrettoPoint> {
/// Compresses the GroupSendEndorsement for storage.
///
/// Serializing an `GroupSendEndorsement<RistrettoPoint>` is equivalent to calling `compress` and
/// serializing the resulting `GroupSendEndorsement<CompressedRistretto>`.
pub fn compress(
self,
) -> GroupSendEndorsement<curve25519_dalek_signal::ristretto::CompressedRistretto> {
) -> GroupSendEndorsement<curve25519_dalek::ristretto::CompressedRistretto> {
GroupSendEndorsement {
reserved: self.reserved,
endorsement: self.endorsement.compress(),
@ -579,7 +576,7 @@ impl GroupSendFullToken {
);
let uid_sho_seed = crypto::uid_struct::UidStruct::seed_M1();
let user_id_sum: curve25519_dalek_signal::RistrettoPoint = user_ids
let user_id_sum: curve25519_dalek::RistrettoPoint = user_ids
.into_iter()
.map(|user_id| crypto::uid_struct::UidStruct::calc_M1(uid_sho_seed.clone(), user_id))
.sum();

View File

@ -3,8 +3,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use poksho::ShoApi;
use poksho::shoapi::ShoApiExt as _;
@ -46,9 +46,7 @@ impl Sho {
}
pub fn get_point_single_elligator(&mut self) -> RistrettoPoint {
RistrettoPoint::from_uniform_bytes_single_elligator(
&self.internal_sho.squeeze_and_ratchet_as_array(),
)
RistrettoPoint::map_to_curve(self.internal_sho.squeeze_and_ratchet_as_array())
}
pub fn get_scalar(&mut self) -> Scalar {

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};
use zkcredential::attributes::PublicAttribute;

View File

@ -8,9 +8,9 @@
use std::sync::LazyLock;
use const_str::hex;
use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -7,8 +7,8 @@
use std::sync::LazyLock;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -5,9 +5,9 @@
#![allow(non_snake_case)]
use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -7,10 +7,10 @@
use std::sync::LazyLock;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption};
use zkcredential::attributes::Attribute;
use crate::common::errors::*;
@ -76,7 +76,7 @@ impl ProfileKeyEncryptionDomain {
let M4 = key_pair
.decrypt_to_second_point(ciphertext)
.map_err(|_| ZkGroupVerificationFailure)?;
let (mask, candidates) = M4.decode_253_bits();
let candidates = M4.map_to_curve_inverse();
let target_M3 = key_pair.a1.invert() * ciphertext.as_points()[0];
let seed_sho = profile_key_struct::ProfileKeyStruct::seed_M3();
@ -85,10 +85,9 @@ impl ProfileKeyEncryptionDomain {
let mut n_found = 0;
#[allow(clippy::needless_range_loop)]
for i in 0..8 {
let is_valid_fe = Choice::from((mask >> i) & 1);
let profile_key_bytes: ProfileKeyBytes = candidates[i];
let profile_key_bytes: CtOption<ProfileKeyBytes> = candidates[i];
for j in 0..8 {
let mut pk = profile_key_bytes;
let mut pk = profile_key_bytes.unwrap_or(Default::default());
if ((j >> 2) & 1) == 1 {
pk[0] |= 0x01;
}
@ -101,11 +100,20 @@ impl ProfileKeyEncryptionDomain {
let M3 =
profile_key_struct::ProfileKeyStruct::calc_M3(seed_sho.clone(), pk, uid_bytes);
let candidate_retval = profile_key_struct::ProfileKeyStruct { bytes: pk, M3, M4 };
let found = M3.ct_eq(&target_M3) & is_valid_fe;
let found = M3.ct_eq(&target_M3) & profile_key_bytes.is_some();
retval.conditional_assign(&candidate_retval, found);
n_found += found.unwrap_u8();
}
}
if cfg!(debug_assertions) {
// Double-check that the negative candidates are always at the end; because we encode
// with map_to_curve_restricted, we should never need to check these.
#[allow(clippy::needless_range_loop)]
for i in 9..16 {
let extra_candidate = candidates[i].unwrap_or([0xFF; 32]);
debug_assert_eq!(extra_candidate[0] & 1, 1);
}
}
if n_found == 1 {
Ok(retval)
} else {

View File

@ -5,7 +5,7 @@
#![allow(non_snake_case)]
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};
use subtle::{Choice, ConditionallySelectable};
@ -27,7 +27,7 @@ impl ProfileKeyStruct {
encoded_profile_key[0] &= 254;
encoded_profile_key[31] &= 63;
let M3 = Self::calc_M3(Self::seed_M3(), profile_key_bytes, uid_bytes);
let M4 = RistrettoPoint::from_uniform_bytes_single_elligator(&encoded_profile_key);
let M4 = RistrettoPoint::map_to_curve_restricted(encoded_profile_key);
ProfileKeyStruct {
bytes: profile_key_bytes,

View File

@ -5,9 +5,9 @@
#![allow(non_snake_case)]
use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::traits::Identity;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::traits::Identity;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};
use zkcredential::attributes::Attribute;

View File

@ -5,9 +5,9 @@
#![allow(non_snake_case)]
use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::scalar::Scalar;
use serde::{Deserialize, Serialize};
use crate::common::sho::Sho;

View File

@ -3,9 +3,9 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use curve25519_dalek_signal::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use curve25519_dalek_signal::scalar::Scalar;
use curve25519_dalek::scalar::Scalar;
use serde::{Deserialize, Serialize};
use crate::common::sho::Sho;

View File

@ -7,7 +7,7 @@
use std::sync::LazyLock;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};
use subtle::{ConditionallySelectable, ConstantTimeEq};

View File

@ -5,7 +5,7 @@
#![allow(non_snake_case)]
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use libsignal_core::ServiceId;
use partial_default::PartialDefault;
use serde::{Deserialize, Serialize};

View File

@ -7,7 +7,7 @@
//!
//! Has to live in zkgroup because they implement zkcredential traits on zkgroup types.
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use poksho::shoapi::ShoApiExt as _;
use poksho::{ShoApi, ShoSha256};
use serde::{Deserialize, Serialize};
@ -443,8 +443,8 @@ struct InverseUidDecryptionKey;
impl zkcredential::attributes::Domain for InverseUidDecryptionKey {
type Attribute = uid_encryption::Ciphertext;
const ID: &'static str = "InverseUidEncryptionDomain_20231011";
fn G_a() -> [curve25519_dalek_signal::RistrettoPoint; 2] {
static STORAGE: std::sync::OnceLock<[curve25519_dalek_signal::RistrettoPoint; 2]> =
fn G_a() -> [curve25519_dalek::RistrettoPoint; 2] {
static STORAGE: std::sync::OnceLock<[curve25519_dalek::RistrettoPoint; 2]> =
std::sync::OnceLock::new();
*zkcredential::attributes::derive_default_generator_points::<Self>(&STORAGE)
}

View File

@ -4,7 +4,7 @@
//
use const_str::hex;
use curve25519_dalek_signal::ristretto::RistrettoPoint;
use curve25519_dalek::ristretto::RistrettoPoint;
use sha2::Sha256;
use zkgroup::{SECONDS_PER_DAY, Timestamp};